From 116ef2e9c7b0a834d0b26df16259b451192b876a Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 13 Oct 2014 15:19:12 +0200 Subject: bsps/arm: Convert PL011 and PL050 console drivers Use Termios device API. --- c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am | 8 +- .../arm/realview-pbx-a9/console/console-config.c | 93 ++++++++++++--------- c/src/lib/libbsp/arm/shared/arm-pl011.c | 79 +++++++----------- c/src/lib/libbsp/arm/shared/arm-pl050.c | 95 +++++++++------------- c/src/lib/libbsp/arm/shared/include/arm-pl011.h | 19 ++++- c/src/lib/libbsp/arm/shared/include/arm-pl050.h | 15 +++- 6 files changed, 153 insertions(+), 156 deletions(-) diff --git a/c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am b/c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am index af87b696e0..42e53fa0d8 100644 --- a/c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am +++ b/c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am @@ -108,12 +108,8 @@ libbsp_a_SOURCES += ../../shared/src/irq-shell.c libbsp_a_SOURCES += ../shared/arm-gic-irq.c # Console -libbsp_a_SOURCES += ../../shared/console.c -libbsp_a_SOURCES += ../../shared/console_control.c -libbsp_a_SOURCES += ../../shared/console_read.c -libbsp_a_SOURCES += ../../shared/console_select.c -libbsp_a_SOURCES += ../../shared/console_write.c -libbsp_a_SOURCES += ../../shared/console-output-char.c +libbsp_a_SOURCES += ../../shared/console-termios-init.c +libbsp_a_SOURCES += ../../shared/console-termios.c libbsp_a_SOURCES += ../../shared/get-serial-mouse-ps2.c libbsp_a_SOURCES += ../shared/arm-pl011.c libbsp_a_SOURCES += ../shared/arm-pl050.c diff --git a/c/src/lib/libbsp/arm/realview-pbx-a9/console/console-config.c b/c/src/lib/libbsp/arm/realview-pbx-a9/console/console-config.c index bc7176535b..1dc77605fe 100644 --- a/c/src/lib/libbsp/arm/realview-pbx-a9/console/console-config.c +++ b/c/src/lib/libbsp/arm/realview-pbx-a9/console/console-config.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -13,53 +13,66 @@ */ #include - -#include +#include #include #include #include #include +#include + +static arm_pl011_context pl011_context = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("PL011"), + .regs = (volatile pl011 *) 0x10009000, + .irq = RVPBXA9_IRQ_UART_0, + .initial_baud = 115200 +}; + +static arm_pl050_context pl050_context = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("PL050"), + .regs = (volatile pl050 *) 0x10007000, + .irq = RVPBXA9_IRQ_KMI1, + .initial_baud = 115200 +}; + +static void output_char(char c) +{ + if (c == '\n') { + arm_pl011_write_polled(&pl011_context.base, '\r'); + } + + arm_pl011_write_polled(&pl011_context.base, c); +} + +static bool pl011_probe(rtems_termios_device_context *base) +{ + BSP_output_char = output_char; + + return arm_pl011_probe(base); +} + +static void output_char_init(char c) +{ + pl011_probe(&pl011_context.base); + output_char(c); +} + +BSP_output_char_function_type BSP_output_char = output_char_init; + +BSP_polling_getchar_function_type BSP_poll_char = NULL; -console_tbl Console_Configuration_Ports[] = { +const console_device console_device_table[] = { { - .sDeviceName = "/dev/ttyS0", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &arm_pl011_fns, - .deviceProbe = NULL, - .pDeviceFlow = NULL, - .ulMargin = 10, - .ulHysteresis = 0, - .pDeviceParams = (void *) 115200, - .ulCtrlPort1 = 0x10009000, - .ulCtrlPort2 = 0, - .ulDataPort = 0, - .getRegister = NULL, - .setRegister = NULL, - .getData = NULL, - .setData = NULL, - .ulClock = 0, - .ulIntVector = RVPBXA9_IRQ_UART_0 + .device_file = "/dev/ttyS0", + .probe = pl011_probe, + .handler = &arm_pl011_fns, + .context = &pl011_context.base }, { - .sDeviceName = SERIAL_MOUSE_DEVICE_PS2, - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &arm_pl050_fns, - .deviceProbe = NULL, - .pDeviceFlow = NULL, - .ulMargin = 10, - .ulHysteresis = 0, - .pDeviceParams = (void *) 115200, - .ulCtrlPort1 = 0x10007000, - .ulCtrlPort2 = 0, - .ulDataPort = 0, - .getRegister = NULL, - .setRegister = NULL, - .getData = NULL, - .setData = NULL, - .ulClock = 0, - .ulIntVector = RVPBXA9_IRQ_KMI1 + .device_file = SERIAL_MOUSE_DEVICE_PS2, + .probe = console_device_probe_default, + .handler = &arm_pl050_fns, + .context = &pl050_context.base } }; -unsigned long Console_Configuration_Count = - RTEMS_ARRAY_SIZE(Console_Configuration_Ports); +const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); diff --git a/c/src/lib/libbsp/arm/shared/arm-pl011.c b/c/src/lib/libbsp/arm/shared/arm-pl011.c index 9d613cf73f..44a409e551 100644 --- a/c/src/lib/libbsp/arm/shared/arm-pl011.c +++ b/c/src/lib/libbsp/arm/shared/arm-pl011.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -13,49 +13,44 @@ */ #include -#include -#include - -static volatile pl011 *pl011_get_regs(int minor) +static volatile pl011 *pl011_get_regs(rtems_termios_device_context *base) { - const console_tbl *ct = Console_Port_Tbl != NULL ? - Console_Port_Tbl[minor] : &Console_Configuration_Ports[minor]; + arm_pl011_context *ctx = (arm_pl011_context *) base; - return (volatile pl011 *) ct->ulCtrlPort1; + return ctx->regs; } -static void pl011_initialize(int minor) + +bool arm_pl011_probe(rtems_termios_device_context *base) { - volatile pl011 *regs = pl011_get_regs(minor); + volatile pl011 *regs = pl011_get_regs(base); regs->uartlcr_h = PL011_UARTLCR_H_WLEN(PL011_UARTLCR_H_WLEN_8); regs->uartcr = PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN; + + return true; } -static int pl011_first_open(int major, int minor, void *arg) +static bool pl011_first_open( + struct rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, + rtems_libio_open_close_args_t *args +) { - rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg; - struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1; - console_data *cd = &Console_Port_Data[minor]; - const console_tbl *ct = Console_Port_Tbl[minor]; + arm_pl011_context *ctx = (arm_pl011_context *) base; - cd->termios_data = tty; - rtems_termios_set_initial_baud(tty, (rtems_termios_baud_t) ct->pDeviceParams); + rtems_termios_set_initial_baud(tty, ctx->initial_baud); - return 0; + return true; } -static int pl011_last_close(int major, int minor, void *arg) +static int pl011_read_polled(rtems_termios_device_context *base) { - return 0; -} - -static int pl011_read_polled(int minor) -{ - volatile pl011 *regs = pl011_get_regs(minor); + volatile pl011 *regs = pl011_get_regs(base); if ((regs->uartfr & PL011_UARTFR_RXFE) != 0) { return -1; @@ -64,9 +59,9 @@ static int pl011_read_polled(int minor) } } -static void pl011_write_polled(int minor, char c) +void arm_pl011_write_polled(rtems_termios_device_context *base, char c) { - volatile pl011 *regs = pl011_get_regs(minor); + volatile pl011 *regs = pl011_get_regs(base); while ((regs->uartfr & PL011_UARTFR_TXFF) != 0) { /* Wait */ @@ -75,34 +70,22 @@ static void pl011_write_polled(int minor, char c) regs->uartdr = PL011_UARTDR_DATA(c); } -static ssize_t pl011_write_support_polled( - int minor, +static void pl011_write_support_polled( + rtems_termios_device_context *base, const char *s, size_t n ) { - ssize_t i = 0; + size_t i; for (i = 0; i < n; ++i) { - pl011_write_polled(minor, s[i]); + arm_pl011_write_polled(base, s[i]); } - - return n; -} - -static int pl011_set_attribues(int minor, const struct termios *term) -{ - return -1; } -const console_fns arm_pl011_fns = { - .deviceProbe = libchip_serial_default_probe, - .deviceFirstOpen = pl011_first_open, - .deviceLastClose = pl011_last_close, - .deviceRead = pl011_read_polled, - .deviceWrite = pl011_write_support_polled, - .deviceInitialize = pl011_initialize, - .deviceWritePolled = pl011_write_polled, - .deviceSetAttributes = pl011_set_attribues, - .deviceOutputUsesInterrupts = false +const rtems_termios_device_handler arm_pl011_fns = { + .first_open = pl011_first_open, + .poll_read = pl011_read_polled, + .write = pl011_write_support_polled, + .mode = TERMIOS_POLLED }; diff --git a/c/src/lib/libbsp/arm/shared/arm-pl050.c b/c/src/lib/libbsp/arm/shared/arm-pl050.c index 292934a8c2..0b645095b5 100644 --- a/c/src/lib/libbsp/arm/shared/arm-pl050.c +++ b/c/src/lib/libbsp/arm/shared/arm-pl050.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -16,22 +16,19 @@ #include #include -#include -#include - -static volatile pl050 *pl050_get_regs(int minor) +static volatile pl050 *pl050_get_regs(rtems_termios_device_context *base) { - const console_tbl *ct = Console_Port_Tbl[minor]; + arm_pl050_context *ctx = (arm_pl050_context *) base; - return (volatile pl050 *) ct->ulCtrlPort1; + return ctx->regs; } static void pl050_interrupt(void *arg) { - int minor = (int) arg; - const console_data *cd = &Console_Port_Data[minor]; - volatile pl050 *regs = pl050_get_regs(minor); + rtems_termios_tty *tty = arg; + rtems_termios_device_context *base = rtems_termios_get_device_context(tty); + volatile pl050 *regs = pl050_get_regs(base); uint32_t kmiir_rx = PL050_KMIIR_KMIRXINTR; uint32_t kmiir_tx = (regs->kmicr & PL050_KMICR_KMITXINTREN) != 0 ? PL050_KMIIR_KMITXINTR : 0; @@ -40,70 +37,68 @@ static void pl050_interrupt(void *arg) if ((kmiir & kmiir_rx) != 0) { char c = (char) PL050_KMIDATA_KMIDATA_GET(regs->kmidata); - rtems_termios_enqueue_raw_characters(cd->termios_data, &c, 1); + rtems_termios_enqueue_raw_characters(tty, &c, 1); } if ((kmiir & kmiir_tx) != 0) { - rtems_termios_dequeue_characters(cd->termios_data, 1); + rtems_termios_dequeue_characters(tty, 1); } } -static void pl050_initialize(int minor) -{ - /* Nothing to do */ -} - -static int pl050_first_open(int major, int minor, void *arg) +static bool pl050_first_open( + struct rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, + rtems_libio_open_close_args_t *args +) { - rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg; - struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1; - console_data *cd = &Console_Port_Data[minor]; - const console_tbl *ct = Console_Port_Tbl[minor]; - volatile pl050 *regs = pl050_get_regs(minor); + arm_pl050_context *ctx = (arm_pl050_context *) base; + volatile pl050 *regs = pl050_get_regs(base); rtems_status_code sc; - cd->termios_data = tty; - rtems_termios_set_initial_baud(tty, (rtems_termios_baud_t) ct->pDeviceParams); + rtems_termios_set_initial_baud(tty, ctx->initial_baud); regs->kmicr = PL050_KMICR_KMIEN | PL050_KMICR_KMIRXINTREN; sc = rtems_interrupt_handler_install( - ct->ulIntVector, - ct->sDeviceName, + ctx->irq, + "PL050", RTEMS_INTERRUPT_UNIQUE, pl050_interrupt, - (void *) minor + tty ); assert(sc == RTEMS_SUCCESSFUL); - return 0; + return true; } -static int pl050_last_close(int major, int minor, void *arg) +static void pl050_last_close( + struct rtems_termios_tty *tty, + rtems_termios_device_context *base, + rtems_libio_open_close_args_t *args +) { - const console_tbl *ct = Console_Port_Tbl[minor]; - volatile pl050 *regs = pl050_get_regs(minor); + arm_pl050_context *ctx = (arm_pl050_context *) base; + volatile pl050 *regs = pl050_get_regs(base); rtems_status_code sc; regs->kmicr = 0; sc = rtems_interrupt_handler_remove( - ct->ulIntVector, + ctx->irq, pl050_interrupt, - (void *) minor + tty ); assert(sc == RTEMS_SUCCESSFUL); - - return 0; } -static ssize_t pl050_write_support( - int minor, +static void pl050_write_support( + rtems_termios_device_context *base, const char *s, size_t n ) { - volatile pl050 *regs = pl050_get_regs(minor); + volatile pl050 *regs = pl050_get_regs(base); if (n > 0) { regs->kmidata = PL050_KMIDATA_KMIDATA(s[0]); @@ -111,23 +106,11 @@ static ssize_t pl050_write_support( } else { regs->kmicr &= ~PL050_KMICR_KMITXINTREN; } - - return 0; -} - -static int pl050_set_attribues(int minor, const struct termios *term) -{ - return -1; } -const console_fns arm_pl050_fns = { - .deviceProbe = libchip_serial_default_probe, - .deviceFirstOpen = pl050_first_open, - .deviceLastClose = pl050_last_close, - .deviceRead = NULL, - .deviceWrite = pl050_write_support, - .deviceInitialize = pl050_initialize, - .deviceWritePolled = NULL, - .deviceSetAttributes = pl050_set_attribues, - .deviceOutputUsesInterrupts = true +const rtems_termios_device_handler arm_pl050_fns = { + .first_open = pl050_first_open, + .last_close = pl050_last_close, + .write = pl050_write_support, + .mode = TERMIOS_IRQ_DRIVEN }; diff --git a/c/src/lib/libbsp/arm/shared/include/arm-pl011.h b/c/src/lib/libbsp/arm/shared/include/arm-pl011.h index 0e1f2ee5bc..08189c477c 100644 --- a/c/src/lib/libbsp/arm/shared/include/arm-pl011.h +++ b/c/src/lib/libbsp/arm/shared/include/arm-pl011.h @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -23,13 +23,26 @@ #ifndef LIBBSP_ARM_SHARED_ARM_PL011_H #define LIBBSP_ARM_SHARED_ARM_PL011_H -#include +#include + +#include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -extern const console_fns arm_pl011_fns; +typedef struct { + rtems_termios_device_context base; + volatile pl011 *regs; + rtems_vector_number irq; + uint32_t initial_baud; +} arm_pl011_context; + +bool arm_pl011_probe(rtems_termios_device_context *base); + +void arm_pl011_write_polled(rtems_termios_device_context *base, char c); + +extern const rtems_termios_device_handler arm_pl011_fns; #ifdef __cplusplus } diff --git a/c/src/lib/libbsp/arm/shared/include/arm-pl050.h b/c/src/lib/libbsp/arm/shared/include/arm-pl050.h index bce33291fc..af4e246124 100644 --- a/c/src/lib/libbsp/arm/shared/include/arm-pl050.h +++ b/c/src/lib/libbsp/arm/shared/include/arm-pl050.h @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -23,13 +23,22 @@ #ifndef LIBBSP_ARM_SHARED_ARM_PL050_H #define LIBBSP_ARM_SHARED_ARM_PL050_H -#include +#include + +#include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -extern const console_fns arm_pl050_fns; +typedef struct { + rtems_termios_device_context base; + volatile pl050 *regs; + rtems_vector_number irq; + uint32_t initial_baud; +} arm_pl050_context; + +extern const rtems_termios_device_handler arm_pl050_fns; #ifdef __cplusplus } -- cgit v1.2.3