bsps: Move console drivers to bsps

This patch is a part of the BSP source reorganization.

Update #3285.
This commit is contained in:
Sebastian Huber
2018-04-19 06:28:01 +02:00
parent 58adad484e
commit d7d66d7d45
236 changed files with 204 additions and 204 deletions

View File

@@ -106,9 +106,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
librtemsbsp_a_SOURCES += ../shared/arm-gic-irq.c
# Console
librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
librtemsbsp_a_SOURCES += console/console-config.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/altera-cyclone-v/console/console-config.c
# Clock
librtemsbsp_a_SOURCES += ../shared/arm-a9mpcore-clock-config.c

View File

@@ -1,158 +0,0 @@
/*
* Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <info@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <libchip/ns16550.h>
#include <rtems/bspIo.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <bsp/alt_clock_manager.h>
#include <bsp/console-termios.h>
#include <bsp/socal/alt_rstmgr.h>
#include <bsp/socal/socal.h>
#include <bsp/socal/alt_uart.h>
#include <bsp/socal/hps.h>
#ifdef BSP_USE_UART_INTERRUPTS
#define DEVICE_FNS &ns16550_handler_interrupt
#else
#define DEVICE_FNS &ns16550_handler_polled
#endif
static uint8_t altera_cyclone_v_uart_get_register(uintptr_t addr, uint8_t i)
{
volatile uint32_t *reg = (volatile uint32_t *) addr;
return (uint8_t) reg [i];
}
static void altera_cyclone_v_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
{
volatile uint32_t *reg = (volatile uint32_t *) addr;
reg [i] = val;
}
static bool altera_cyclone_v_uart_probe(
rtems_termios_device_context *base,
uint32_t uart_set_mask
)
{
ns16550_context *ctx = (ns16550_context *) base;
bool ret = true;
uint32_t ucr;
ALT_STATUS_CODE sc;
void* location = (void *) ctx->port;
/* The ALT_CLK_L4_SP is required for all SoCFPGA UARTs.
* Check that it's enabled. */
if ( alt_clk_is_enabled(ALT_CLK_L4_SP) != ALT_E_TRUE ) {
ret = false;
}
if ( ret ) {
sc = alt_clk_freq_get(ALT_CLK_L4_SP, &ctx->clock);
if ( sc != ALT_E_SUCCESS ) {
ret = false;
}
}
if ( ret ) {
// Bring UART out of reset.
alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, uart_set_mask);
// Verify the UCR (UART Component Version)
ucr = alt_read_word( ALT_UART_UCV_ADDR( location ) );
if ( ucr != ALT_UART_UCV_UART_COMPONENT_VER_RESET ) {
ret = false;
}
}
if ( ret ) {
// Write SRR::UR (Shadow Reset Register :: UART Reset)
alt_write_word( ALT_UART_SRR_ADDR( location ), ALT_UART_SRR_UR_SET_MSK );
// Read the MSR to work around case:119085.
(void)alt_read_word( ALT_UART_MSR_ADDR( location ) );
ret = ns16550_probe( base );
}
return ret;
}
#ifdef CYCLONE_V_CONFIG_CONSOLE
static bool altera_cyclone_v_uart_probe_0(rtems_termios_device_context *base)
{
return altera_cyclone_v_uart_probe(base, ALT_RSTMGR_PERMODRST_UART0_SET_MSK);
}
static ns16550_context altera_cyclone_v_uart_context_0 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"),
.get_reg = altera_cyclone_v_uart_get_register,
.set_reg = altera_cyclone_v_uart_set_register,
.port = (uintptr_t) ALT_UART0_ADDR,
.irq = ALT_INT_INTERRUPT_UART0,
.initial_baud = CYCLONE_V_UART_BAUD
};
#endif
#ifdef CYCLONE_V_CONFIG_UART_1
static bool altera_cyclone_v_uart_probe_1(rtems_termios_device_context *base)
{
return altera_cyclone_v_uart_probe(base, ALT_RSTMGR_PERMODRST_UART1_SET_MSK);
}
static ns16550_context altera_cyclone_v_uart_context_1 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"),
.get_reg = altera_cyclone_v_uart_get_register,
.set_reg = altera_cyclone_v_uart_set_register,
.port = (uintptr_t) ALT_UART1_ADDR,
.irq = ALT_INT_INTERRUPT_UART1,
.initial_baud = CYCLONE_V_UART_BAUD
};
#endif
const console_device console_device_table[] = {
#ifdef CYCLONE_V_CONFIG_CONSOLE
{
.device_file = "/dev/ttyS0",
.probe = altera_cyclone_v_uart_probe_0,
.handler = DEVICE_FNS,
.context = &altera_cyclone_v_uart_context_0.base
},
#endif
#ifdef CYCLONE_V_CONFIG_UART_1
{
.device_file = "/dev/ttyS1",
.probe = altera_cyclone_v_uart_probe_1,
.handler = DEVICE_FNS,
.context = &altera_cyclone_v_uart_context_1.base
},
#endif
};
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
static void output_char(char c)
{
rtems_termios_device_context *ctx = console_device_table[0].context;
ns16550_polled_putchar( ctx, c );
}
BSP_output_char_function_type BSP_output_char = output_char;
BSP_polling_getchar_function_type BSP_poll_char = NULL;

View File

@@ -113,9 +113,9 @@ librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq.c
librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq-dispatch.c
# Console
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
librtemsbsp_a_SOURCES += console/console.c
librtemsbsp_a_SOURCES += console/debug-console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/console/console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/console/debug-console.c
# Clock
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-armv7m.c

View File

@@ -1,526 +0,0 @@
/*
* Copyright (c) 2016 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <bsp/irq.h>
#include <bsp/fatal.h>
#include <rtems/console.h>
#include <rtems/termiostypes.h>
#include <chip.h>
#include <unistd.h>
typedef struct {
rtems_termios_device_context base;
Usart *regs;
rtems_vector_number irq;
uint32_t id;
bool console;
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
bool transmitting;
#endif
} atsam_usart_context;
static atsam_usart_context atsam_usart_instances[] = {
{
.regs = USART0,
.irq = USART0_IRQn,
.id = ID_USART0
}
#ifdef USART1
, {
.regs = USART1,
.irq = USART1_IRQn,
.id = ID_USART1
}
#endif
#ifdef USART2
, {
.regs = USART2,
.irq = USART2_IRQn,
.id = ID_USART2
}
#endif
};
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
static void atsam_usart_interrupt(void *arg)
{
rtems_termios_tty *tty = arg;
atsam_usart_context *ctx = rtems_termios_get_device_context(tty);
Usart *regs = ctx->regs;
uint32_t csr = regs->US_CSR;
while ((csr & US_CSR_RXRDY) != 0) {
char c = (char) regs->US_RHR;
rtems_termios_enqueue_raw_characters(tty, &c, 1);
csr = regs->US_CSR;
}
if (ctx->transmitting && (csr & US_CSR_TXEMPTY) != 0) {
rtems_termios_dequeue_characters(tty, 1);
}
}
#endif
static bool atsam_usart_set_attributes(
rtems_termios_device_context *base,
const struct termios *term
)
{
atsam_usart_context *ctx = (atsam_usart_context *) base;
Usart *regs = ctx->regs;
rtems_termios_baud_t baud;
uint32_t mr;
baud = rtems_termios_baud_to_number(term->c_ospeed);
regs->US_BRGR = (BOARD_MCK / baud) / 16;
if ((term->c_cflag & CREAD) != 0) {
regs->US_CR = US_CR_RXEN | US_CR_TXEN;
} else {
regs->US_CR = US_CR_TXEN;
}
mr = US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK;
switch (term->c_cflag & CSIZE) {
case CS5:
mr |= US_MR_CHRL_5_BIT;
break;
case CS6:
mr |= US_MR_CHRL_6_BIT;
break;
case CS7:
mr |= US_MR_CHRL_7_BIT;
break;
default:
mr |= US_MR_CHRL_8_BIT;
break;
}
if ((term->c_cflag & PARENB) != 0) {
if ((term->c_cflag & PARODD) != 0) {
mr |= US_MR_PAR_ODD;
} else {
mr |= US_MR_PAR_EVEN;
}
} else {
mr |= US_MR_PAR_NO;
}
if ((term->c_cflag & CSTOPB) != 0) {
mr |= US_MR_NBSTOP_2_BIT;
} else {
mr |= US_MR_NBSTOP_1_BIT;
}
regs->US_MR = mr;
return true;
}
static bool atsam_usart_first_open(
rtems_termios_tty *tty,
rtems_termios_device_context *base,
struct termios *term,
rtems_libio_open_close_args_t *args
)
{
atsam_usart_context *ctx = (atsam_usart_context *) base;
Usart *regs = ctx->regs;
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
rtems_status_code sc;
#endif
regs->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RSTSTA;
regs->US_IDR = 0xffffffff;
PMC_EnablePeripheral(ctx->id);
rtems_termios_set_initial_baud(tty, ATSAM_CONSOLE_BAUD);
atsam_usart_set_attributes(base, term);
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
regs->US_IER = US_IDR_RXRDY;
sc = rtems_interrupt_handler_install(
ctx->irq,
"USART",
RTEMS_INTERRUPT_SHARED,
atsam_usart_interrupt,
tty
);
if (sc != RTEMS_SUCCESSFUL) {
return false;
}
#endif
return true;
}
static void atsam_usart_last_close(
rtems_termios_tty *tty,
rtems_termios_device_context *base,
rtems_libio_open_close_args_t *args
)
{
atsam_usart_context *ctx = (atsam_usart_context *) base;
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
rtems_interrupt_handler_remove(ctx->irq, atsam_usart_interrupt, tty);
#endif
if (!ctx->console) {
PMC_DisablePeripheral(ctx->id);
}
}
static void atsam_usart_write(
rtems_termios_device_context *base,
const char *buf,
size_t len
)
{
atsam_usart_context *ctx = (atsam_usart_context *) base;
Usart *regs = ctx->regs;
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
if (len > 0) {
ctx->transmitting = true;
regs->US_THR = buf[0];
regs->US_IER = US_IDR_TXEMPTY;
} else {
ctx->transmitting = false;
regs->US_IDR = US_IDR_TXEMPTY;
}
#else
size_t i;
for (i = 0; i < len; ++i) {
while ((regs->US_CSR & US_CSR_TXEMPTY) == 0) {
/* Wait */
}
regs->US_THR = buf[i];
}
#endif
}
#ifndef ATSAM_CONSOLE_USE_INTERRUPTS
static int atsam_usart_read(rtems_termios_device_context *base)
{
atsam_usart_context *ctx = (atsam_usart_context *) base;
Usart *regs = ctx->regs;
if ((regs->US_CSR & US_CSR_RXRDY) != 0) {
return (char) regs->US_RHR;
} else {
return -1;
}
}
#endif
static const rtems_termios_device_handler atsam_usart_handler = {
.first_open = atsam_usart_first_open,
.last_close = atsam_usart_last_close,
.write = atsam_usart_write,
.set_attributes = atsam_usart_set_attributes,
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
.mode = TERMIOS_IRQ_DRIVEN
#else
.poll_read = atsam_usart_read,
.mode = TERMIOS_POLLED
#endif
};
typedef struct {
rtems_termios_device_context base;
Uart *regs;
rtems_vector_number irq;
uint32_t id;
bool console;
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
bool transmitting;
#endif
} atsam_uart_context;
static atsam_uart_context atsam_uart_instances[] = {
{
.regs = UART0,
.irq = UART0_IRQn,
.id = ID_UART0
}
#ifdef UART1
, {
.regs = UART1,
.irq = UART1_IRQn,
.id = ID_UART1
}
#endif
#ifdef UART2
, {
.regs = UART2,
.irq = UART2_IRQn,
.id = ID_UART2
}
#endif
#ifdef UART3
, {
.regs = UART3,
.irq = UART3_IRQn,
.id = ID_UART3
}
#endif
#ifdef UART4
, {
.regs = UART4,
.irq = UART4_IRQn,
.id = ID_UART4
}
#endif
};
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
static void atsam_uart_interrupt(void *arg)
{
rtems_termios_tty *tty = arg;
atsam_uart_context *ctx = rtems_termios_get_device_context(tty);
Uart *regs = ctx->regs;
uint32_t sr = regs->UART_SR;
while ((sr & UART_SR_RXRDY) != 0) {
char c = (char) regs->UART_RHR;
rtems_termios_enqueue_raw_characters(tty, &c, 1);
sr = regs->UART_SR;
}
if (ctx->transmitting && (sr & UART_SR_TXEMPTY) != 0) {
rtems_termios_dequeue_characters(tty, 1);
}
}
#endif
static bool atsam_uart_set_attributes(
rtems_termios_device_context *base,
const struct termios *term
)
{
atsam_uart_context *ctx = (atsam_uart_context *) base;
Uart *regs = ctx->regs;
rtems_termios_baud_t baud;
uint32_t mr;
baud = rtems_termios_baud_to_number(term->c_ospeed);
regs->UART_BRGR = (BOARD_MCK / baud) / 16;
if ((term->c_cflag & CREAD) != 0) {
regs->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
} else {
regs->UART_CR = UART_CR_TXEN;
}
mr = UART_MR_FILTER_DISABLED | UART_MR_BRSRCCK_PERIPH_CLK;
if ((term->c_cflag & CSIZE) != CS8) {
return false;
}
if ((term->c_cflag & PARENB) != 0) {
if ((term->c_cflag & PARODD) != 0) {
mr |= UART_MR_PAR_ODD;
} else {
mr |= UART_MR_PAR_EVEN;
}
} else {
mr |= UART_MR_PAR_NO;
}
if ((term->c_cflag & CSTOPB) != 0) {
return false;
}
regs->UART_MR = mr;
return true;
}
static bool atsam_uart_first_open(
rtems_termios_tty *tty,
rtems_termios_device_context *base,
struct termios *term,
rtems_libio_open_close_args_t *args
)
{
atsam_uart_context *ctx = (atsam_uart_context *) base;
Uart *regs = ctx->regs;
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
rtems_status_code sc;
#endif
regs->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RSTSTA;
regs->UART_IDR = 0xffffffff;
PMC_EnablePeripheral(ctx->id);
rtems_termios_set_initial_baud(tty, ATSAM_CONSOLE_BAUD);
atsam_uart_set_attributes(base, term);
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
regs->UART_IER = UART_IDR_RXRDY;
sc = rtems_interrupt_handler_install(
ctx->irq,
"UART",
RTEMS_INTERRUPT_SHARED,
atsam_uart_interrupt,
tty
);
if (sc != RTEMS_SUCCESSFUL) {
return false;
}
#endif
return true;
}
static void atsam_uart_last_close(
rtems_termios_tty *tty,
rtems_termios_device_context *base,
rtems_libio_open_close_args_t *args
)
{
atsam_uart_context *ctx = (atsam_uart_context *) base;
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
rtems_interrupt_handler_remove(ctx->irq, atsam_uart_interrupt, tty);
#endif
if (!ctx->console) {
PMC_DisablePeripheral(ctx->id);
}
}
static void atsam_uart_write(
rtems_termios_device_context *base,
const char *buf,
size_t len
)
{
atsam_uart_context *ctx = (atsam_uart_context *) base;
Uart *regs = ctx->regs;
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
if (len > 0) {
ctx->transmitting = true;
regs->UART_THR = buf[0];
regs->UART_IER = UART_IDR_TXEMPTY;
} else {
ctx->transmitting = false;
regs->UART_IDR = UART_IDR_TXEMPTY;
}
#else
size_t i;
for (i = 0; i < len; ++i) {
while ((regs->UART_SR & UART_SR_TXEMPTY) == 0) {
/* Wait */
}
regs->UART_THR = buf[i];
}
#endif
}
#ifndef ATSAM_CONSOLE_USE_INTERRUPTS
static int atsam_uart_read(rtems_termios_device_context *base)
{
atsam_uart_context *ctx = (atsam_uart_context *) base;
Uart *regs = ctx->regs;
if ((regs->UART_SR & UART_SR_RXRDY) != 0) {
return (char) regs->UART_RHR;
} else {
return -1;
}
}
#endif
static const rtems_termios_device_handler atsam_uart_handler = {
.first_open = atsam_uart_first_open,
.last_close = atsam_uart_last_close,
.write = atsam_uart_write,
.set_attributes = atsam_uart_set_attributes,
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
.mode = TERMIOS_IRQ_DRIVEN
#else
.poll_read = atsam_uart_read,
.mode = TERMIOS_POLLED
#endif
};
rtems_status_code console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
size_t i;
rtems_termios_initialize();
for (i = 0; i < RTEMS_ARRAY_SIZE(atsam_usart_instances); ++i) {
char usart[] = "/dev/ttyUSARTX";
usart[sizeof(usart) - 2] = (char) ('0' + i);
rtems_termios_device_install(
&usart[0],
&atsam_usart_handler,
NULL,
&atsam_usart_instances[i].base
);
#if ATSAM_CONSOLE_DEVICE_TYPE == 0
if (i == ATSAM_CONSOLE_DEVICE_INDEX) {
atsam_usart_instances[i].console = true;
link(&usart[0], CONSOLE_DEVICE_NAME);
}
#endif
}
for (i = 0; i < RTEMS_ARRAY_SIZE(atsam_uart_instances); ++i) {
char uart[] = "/dev/ttyUARTX";
uart[sizeof(uart) - 2] = (char) ('0' + i);
rtems_termios_device_install(
&uart[0],
&atsam_uart_handler,
NULL,
&atsam_uart_instances[i].base
);
#if ATSAM_CONSOLE_DEVICE_TYPE == 1
if (i == ATSAM_CONSOLE_DEVICE_INDEX) {
atsam_uart_instances[i].console = true;
link(&uart[0], CONSOLE_DEVICE_NAME);
}
#endif
}
return RTEMS_SUCCESSFUL;
}

View File

@@ -1,52 +0,0 @@
/*
* Copyright (c) 2016 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems/bspIo.h>
#include <rtems/sysinit.h>
#include <bsp/atsam-clock-config.h>
#include <chip.h>
#include <include/dbg_console.h>
static void atsam_debug_console_out(char c)
{
DBG_PutChar((uint8_t) c);
}
static void atsam_debug_console_init(void)
{
DBG_Configure(115200, BOARD_MCK);
BSP_output_char = atsam_debug_console_out;
}
static void atsam_debug_console_early_init(char c)
{
atsam_debug_console_init();
atsam_debug_console_out(c);
}
static int atsam_debug_console_in(void)
{
return (int) DBG_GetChar();
}
BSP_output_char_function_type BSP_output_char = atsam_debug_console_early_init;
BSP_polling_getchar_function_type BSP_poll_char = atsam_debug_console_in;
RTEMS_SYSINIT_ITEM(
atsam_debug_console_init,
RTEMS_SYSINIT_BSP_START,
RTEMS_SYSINIT_ORDER_LAST
);

View File

@@ -65,7 +65,7 @@ librtemsbsp_a_SOURCES += irq.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
librtemsbsp_a_SOURCES += console/console-config.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/beagle/console/console-config.c
# I2C
librtemsbsp_a_SOURCES += i2c/bbb-i2c.c

View File

@@ -1,152 +0,0 @@
/**
* @file
*
* @ingroup arm_beagle
*
* @brief Console configuration.
*/
/*
* Copyright (c) 2012 Claas Ziemke. All rights reserved.
*
* Claas Ziemke
* Kernerstrasse 11
* 70182 Stuttgart
* Germany
* <claas.ziemke@gmx.net>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Modified by Ben Gras <beng@shrike-systems.com> to make
* interrupt-driven uart i/o work for beagleboards; beaglebone support added.
*/
#include <libchip/serial.h>
#include <libchip/ns16550.h>
#include <rtems/bspIo.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <bsp/uart-output-char.h>
#define CONSOLE_UART_THR (*(volatile unsigned int *)BSP_CONSOLE_UART_BASE)
#define CONSOLE_UART_RHR (*(volatile unsigned int *)BSP_CONSOLE_UART_BASE)
#define CONSOLE_UART_LSR (*(volatile unsigned int *)(BSP_CONSOLE_UART_BASE+0x14))
#define CONSOLE_SYSC (*(volatile uint32_t *) (BSP_CONSOLE_UART_BASE + 0x54))
#define CONSOLE_SYSS (*(volatile uint32_t *) (BSP_CONSOLE_UART_BASE + 0x58))
#define TX_FIFO_E (1<<5)
#define RX_FIFO_E (1<<0)
static uint8_t beagle_uart_get_register(uintptr_t addr, uint8_t i)
{
uint8_t v;
volatile uint32_t *reg_r = (volatile uint32_t *) addr + i;
if(reg_r == (uint32_t*) BSP_CONSOLE_UART_BASE /* reading RHR */ ) {
/* check there should be anything in the RHR before accessing it */
if(!(CONSOLE_UART_LSR & 0x01)) {
return 0;
}
}
v = (uint8_t) *reg_r;
return v;
}
static void beagle_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
{
volatile uint32_t *reg = (volatile uint32_t *) addr;
reg [i] = val;
}
console_tbl Console_Configuration_Ports [] = {
{
.sDeviceName = "/dev/ttyS0",
.deviceType = SERIAL_NS16550,
#if CONSOLE_POLLED /* option to facilitate running the tests */
.pDeviceFns = &ns16550_fns_polled,
#else
.pDeviceFns = &ns16550_fns,
#endif
.ulMargin = 16,
.ulHysteresis = 8,
.pDeviceParams = (void *) CONSOLE_BAUD,
.ulCtrlPort1 = BSP_CONSOLE_UART_BASE,
.ulDataPort = BSP_CONSOLE_UART_BASE,
.ulIntVector = BSP_CONSOLE_UART_IRQ,
.getRegister = beagle_uart_get_register,
.setRegister = beagle_uart_set_register,
.ulClock = UART_CLOCK, /* 48MHz base clock */
},
};
unsigned long Console_Configuration_Count = 1;
static int init_needed = 1; // don't rely on bss being 0
static void beagle_console_init(void)
{
if(init_needed) {
const uint32_t div = UART_CLOCK / 16 / CONSOLE_BAUD;
CONSOLE_SYSC = 2;
while ((CONSOLE_SYSS & 1) == 0)
;
if ((CONSOLE_LSR & (CONSOLE_LSR_THRE | CONSOLE_LSR_TEMT)) == CONSOLE_LSR_THRE) {
CONSOLE_LCR = 0x83;
CONSOLE_DLL = div;
CONSOLE_DLM = (div >> 8) & 0xff;
CONSOLE_LCR = 0x03;
CONSOLE_ACR = 0x00;
}
while ((CONSOLE_LSR & CONSOLE_LSR_TEMT) == 0)
;
CONSOLE_LCR = 0x80 | 0x03;
CONSOLE_DLL = 0x00;
CONSOLE_DLM = 0x00;
CONSOLE_LCR = 0x03;
CONSOLE_MCR = 0x03;
CONSOLE_FCR = 0x07;
CONSOLE_LCR = 0x83;
CONSOLE_DLL = div;
CONSOLE_DLM = (div >> 8) & 0xff;
CONSOLE_LCR = 0x03;
CONSOLE_ACR = 0x00;
init_needed = 0;
}
}
#define CONSOLE_THR8 (*(volatile uint8_t *) (BSP_CONSOLE_UART_BASE + 0x00))
static void uart_write_polled( char c )
{
if(init_needed) beagle_console_init();
while( ( CONSOLE_LSR & TX_FIFO_E ) == 0 )
;
CONSOLE_THR8 = c;
}
static void _BSP_put_char( char c ) {
uart_write_polled( c );
}
static int _BSP_get_char(void)
{
if ((CONSOLE_LSR & CONSOLE_LSR_RDR) != 0) {
return CONSOLE_RBR;
} else {
return -1;
}
}
BSP_output_char_function_type BSP_output_char = _BSP_put_char;
BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;

View File

@@ -30,7 +30,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/cpucounter/cpucounter
librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/csb336/clock/clockdrv.c
librtemsbsp_a_SOURCES += timer/timer.c
# console
librtemsbsp_a_SOURCES += console/uart.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb336/console/uart.c
# IRQ
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
librtemsbsp_a_SOURCES += irq/irq.c

View File

@@ -1,476 +0,0 @@
/*
* Console driver for MC9328XML UARTs.
*
* Written Jay Monkman <jtm@lopingdog.com>
* Copyright (c) 2005 by Loping Dog Embedded Systems
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license
*/
#include <bsp.h>
#include <rtems/libio.h>
#include <libchip/sersupp.h>
#include <rtems/error.h>
#include <rtems/bspIo.h>
#include <assert.h>
#include <termios.h>
#include <rtems/irq.h>
#include <bsp/irq.h>
#include <mc9328mxl.h>
#include <rtems/console.h>
#include <inttypes.h>
/* Define this to use interrupt driver UART driver */
#define USE_INTERRUPTS 1
/* How many serial ports? */
#define NUM_DEVS 2
#define poll_write(c) imx_uart_poll_write_char(0, c)
#define poll_read() imx_uart_poll_read_char(0)
static int imx_uart_first_open(int, int, void *);
static int imx_uart_last_close(int, int, void *);
static int imx_uart_poll_read(int);
static int imx_uart_set_attrs(int, const struct termios *);
static void imx_uart_init(int minor);
static void imx_uart_set_baud(int, int);
static ssize_t imx_uart_poll_write(int, const char *, size_t);
static int imx_uart_poll_read_char(int minor);
static void imx_uart_poll_write_char(int minor, char c);
static void _BSP_output_char(char c);
static int _BSP_poll_char(void);
#if USE_INTERRUPTS
static void imx_uart_tx_isr(void *);
static void imx_uart_rx_isr(void *);
static void imx_uart_isr_on(rtems_vector_number);
static void imx_uart_isr_off(rtems_vector_number);
static ssize_t imx_uart_intr_write(int, const char *, size_t);
static rtems_vector_number imx_uart_name_transmit(int minor);
static rtems_vector_number imx_uart_name_receive(int minor);
#endif
/* TERMIOS callbacks */
#if USE_INTERRUPTS
rtems_termios_callbacks imx_uart_cbacks = {
.firstOpen = imx_uart_first_open,
.lastClose = imx_uart_last_close,
.pollRead = NULL,
.write = imx_uart_intr_write,
.setAttributes = imx_uart_set_attrs,
.stopRemoteTx = NULL,
.startRemoteTx = NULL,
.outputUsesInterrupts = 1,
};
#else
rtems_termios_callbacks imx_uart_cbacks = {
.firstOpen = imx_uart_first_open,
.lastClose = imx_uart_last_close,
.pollRead = imx_uart_poll_read,
.write = imx_uart_poll_write,
.setAttributes = imx_uart_set_attrs,
.stopRemoteTx = NULL,
.startRemoteTx = NULL,
.outputUsesInterrupts = 0,
};
#endif
typedef struct {
int minor;
mc9328mxl_uart_regs_t * regs;
volatile const char *buf;
volatile int len;
volatile int idx;
void *tty;
} imx_uart_data_t;
static imx_uart_data_t imx_uart_data[NUM_DEVS];
rtems_device_driver console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code status;
int i;
for (i = 0; i < NUM_DEVS; i++) {
imx_uart_init(i);
}
rtems_termios_initialize();
/* /dev/console and /dev/tty0 are the same */
status = rtems_io_register_name("/dev/console", major, 0);
if (status != RTEMS_SUCCESSFUL) {
rtems_panic("%s:%d Error registering /dev/console :: %d\n",
__FUNCTION__, __LINE__, status);
}
status = rtems_io_register_name("/dev/tty0", major, 0);
if (status != RTEMS_SUCCESSFUL) {
rtems_panic("%s:%d Error registering /dev/tty0 :: %d\n",
__FUNCTION__, __LINE__, status);
}
status = rtems_io_register_name("/dev/tty1", major, 1);
if (status != RTEMS_SUCCESSFUL) {
rtems_panic("%s:%d Error registering /dev/tty1 :: %d\n",
__FUNCTION__, __LINE__, status);
}
return RTEMS_SUCCESSFUL;
}
rtems_device_driver console_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
rtems_status_code rc;
if (minor > (NUM_DEVS - 1)) {
return RTEMS_INVALID_NUMBER;
}
rc = rtems_termios_open(major, minor, arg, &imx_uart_cbacks);
return rc;
}
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);
}
static void imx_uart_init(int minor)
{
imx_uart_data[minor].minor = minor;
imx_uart_data[minor].buf = NULL;
imx_uart_data[minor].len = 0;
imx_uart_data[minor].idx = 0;
if (minor == 0) {
imx_uart_data[minor].regs =
(mc9328mxl_uart_regs_t *) MC9328MXL_UART1_BASE;
} else if (minor == 1) {
imx_uart_data[minor].regs =
(mc9328mxl_uart_regs_t *) MC9328MXL_UART2_BASE;
} else {
rtems_panic("%s:%d Unknown UART minor number %d\n",
__FUNCTION__, __LINE__, minor);
}
imx_uart_data[minor].regs->cr1 = (
MC9328MXL_UART_CR1_UARTCLKEN |
MC9328MXL_UART_CR1_UARTEN);
imx_uart_data[minor].regs->cr2 = (
MC9328MXL_UART_CR2_IRTS |
MC9328MXL_UART_CR2_WS |
MC9328MXL_UART_CR2_TXEN |
MC9328MXL_UART_CR2_RXEN |
MC9328MXL_UART_CR2_SRST);
imx_uart_data[minor].regs->cr3 = 0;
imx_uart_data[minor].regs->cr4 = 0;
imx_uart_data[minor].regs->fcr = (
MC9328MXL_UART_FCR_TXTL(32) |
MC9328MXL_UART_FCR_RFDIV_1 |
MC9328MXL_UART_FCR_RXTL(1));
imx_uart_set_baud(minor, 38400);
}
static int imx_uart_first_open(int major, int minor, void *arg)
{
rtems_libio_open_close_args_t *args = arg;
rtems_status_code status = RTEMS_SUCCESSFUL;
imx_uart_data[minor].tty = args->iop->data1;
#if USE_INTERRUPTS
status = rtems_interrupt_handler_install(
imx_uart_name_transmit(minor),
"UART",
RTEMS_INTERRUPT_UNIQUE,
imx_uart_tx_isr,
&imx_uart_data[minor]
);
assert(status == RTEMS_SUCCESSFUL);
imx_uart_isr_on(imx_uart_name_transmit(minor));
status = rtems_interrupt_handler_install(
imx_uart_name_receive(minor),
"UART",
RTEMS_INTERRUPT_UNIQUE,
imx_uart_rx_isr,
&imx_uart_data[minor]
);
assert(status == RTEMS_SUCCESSFUL);
imx_uart_isr_on(imx_uart_name_receive(minor));
imx_uart_data[minor].regs->cr1 |= MC9328MXL_UART_CR1_RRDYEN;
#endif
return 0;
}
static int imx_uart_last_close(int major, int minor, void *arg)
{
#if USE_INTERRUPTS
rtems_status_code status = RTEMS_SUCCESSFUL;
imx_uart_isr_off(imx_uart_name_transmit(minor));
status = rtems_interrupt_handler_remove(
imx_uart_name_transmit(minor),
imx_uart_tx_isr,
&imx_uart_data[minor]
);
assert(status == RTEMS_SUCCESSFUL);
imx_uart_isr_off(imx_uart_name_receive(minor));
status = rtems_interrupt_handler_remove(
imx_uart_name_receive(minor),
imx_uart_rx_isr,
&imx_uart_data[minor]
);
assert(status == RTEMS_SUCCESSFUL);
#endif
return 0;
}
static int imx_uart_poll_read(int minor)
{
if (imx_uart_data[minor].regs->sr2 & MC9328MXL_UART_SR2_RDR) {
return imx_uart_data[minor].regs->rxd & 0xff;
} else {
return -1;
}
}
static ssize_t imx_uart_poll_write(int minor, const char *buf, size_t len)
{
int i;
for (i = 0; i < len; i++) {
/* Wait for there to be room in the fifo */
while (!(imx_uart_data[minor].regs->sr2 & MC9328MXL_UART_SR2_TXDC)) {
continue;
}
imx_uart_data[minor].regs->txd = buf[i];
}
return 1;
}
#if USE_INTERRUPTS
static ssize_t imx_uart_intr_write(int minor, const char *buf, size_t len)
{
if (len > 0) {
imx_uart_data[minor].buf = buf;
imx_uart_data[minor].len = len;
imx_uart_data[minor].idx = 0;
imx_uart_data[minor].regs->cr1 |= MC9328MXL_UART_CR1_TXMPTYEN;
}
return 1;
}
#endif
/* This is for setting baud rate, bits, etc. */
static int imx_uart_set_attrs(int minor, const struct termios *t)
{
int baud;
baud = rtems_termios_baud_to_number(t->c_ospeed);
imx_uart_set_baud(minor, baud);
return 0;
}
#if USE_INTERRUPTS
static void imx_uart_isr_on(rtems_vector_number name)
{
MC9328MXL_AITC_INTENNUM = name;
}
static void imx_uart_isr_off(rtems_vector_number name)
{
MC9328MXL_AITC_INTDISNUM = name;
}
static void imx_uart_rx_isr(void * param)
{
imx_uart_data_t *uart_data = param;
char buf[32];
int i=0;
while (uart_data->regs->sr2 & MC9328MXL_UART_SR2_RDR) {
buf[i] = uart_data->regs->rxd & 0xff;
i++;
}
rtems_termios_enqueue_raw_characters(uart_data->tty, buf, i);
}
static void imx_uart_tx_isr(void * param)
{
imx_uart_data_t *uart_data = param;
int len;
int minor = uart_data->minor;
if (uart_data->idx < uart_data->len) {
while ( (uart_data->regs->sr1 & MC9328MXL_UART_SR1_TRDY) &&
(uart_data->idx < uart_data->len)) {
uart_data->regs->txd = uart_data->buf[uart_data->idx];
uart_data->idx++;
}
} else {
len = uart_data->len;
uart_data->len = 0;
imx_uart_data[minor].regs->cr1 &= ~MC9328MXL_UART_CR1_TXMPTYEN;
rtems_termios_dequeue_characters(uart_data->tty, len);
}
}
static rtems_vector_number imx_uart_name_transmit(int minor)
{
if (minor == 0) {
return BSP_INT_UART1_TX;
} else if (minor == 1) {
return BSP_INT_UART2_TX;
}
assert(0);
}
static rtems_vector_number imx_uart_name_receive(int minor)
{
if (minor == 0) {
return BSP_INT_UART1_RX;
} else if (minor == 1) {
return BSP_INT_UART2_RX;
}
assert(0);
}
#endif
/*
* Set the UART's baud rate. The calculation is:
* (baud * 16) / ref_freq = num/demom
*
* ref_freq = perclk1 / RFDIV[2:0]
* BIR = num - 1
* BMR = demom - 1
*
* Setting 'num' to 16 yields this equation:
* demom = ref_freq / baud
*/
static void imx_uart_set_baud(int minor, int baud)
{
unsigned int perclk1;
unsigned int denom;
unsigned int ref_freq = 0;
uint32_t fcr;
perclk1 = get_perclk1_freq();
fcr = imx_uart_data[minor].regs->fcr;
switch(fcr & MC9328MXL_UART_FCR_RFDIV_MASK) {
case MC9328MXL_UART_FCR_RFDIV_1: ref_freq = perclk1/1; break;
case MC9328MXL_UART_FCR_RFDIV_2: ref_freq = perclk1/2; break;
case MC9328MXL_UART_FCR_RFDIV_3: ref_freq = perclk1/3; break;
case MC9328MXL_UART_FCR_RFDIV_4: ref_freq = perclk1/4; break;
case MC9328MXL_UART_FCR_RFDIV_5: ref_freq = perclk1/5; break;
case MC9328MXL_UART_FCR_RFDIV_6: ref_freq = perclk1/6; break;
case MC9328MXL_UART_FCR_RFDIV_7: ref_freq = perclk1/7; break;
default:
rtems_panic("%s:%d Unknown RFDIV: 0x%" PRIx32,
__FUNCTION__, __LINE__,
fcr & MC9328MXL_UART_FCR_RFDIV_MASK);
break;
}
denom = ref_freq / baud;
imx_uart_data[minor].regs->bir = 0xf;
imx_uart_data[minor].regs->bmr = denom;
}
/*
* Polled, non-blocking read from UART
*/
static int imx_uart_poll_read_char(int minor)
{
return imx_uart_poll_read(minor);
}
/*
* Polled, blocking write from UART
*/
static void imx_uart_poll_write_char(int minor, char c)
{
imx_uart_poll_write(minor, &c, 1);
}
/*
* Functions for printk() and friends.
*/
static void _BSP_output_char(char c)
{
poll_write(c);
}
BSP_output_char_function_type BSP_output_char = _BSP_output_char;
static int _BSP_poll_char(void)
{
return poll_read();
}
BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char;

View File

@@ -43,15 +43,15 @@ librtemsbsp_a_SOURCES += timer/timer.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
librtemsbsp_a_SOURCES += console/uarts.c
librtemsbsp_a_SOURCES += console/dbgu.c
librtemsbsp_a_SOURCES += console/usart.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/uarts.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/dbgu.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/usart.c
# IRQ
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
librtemsbsp_a_SOURCES += irq/irq.c
if ENABLE_LCD
librtemsbsp_a_SOURCES += console/sed1356.c
librtemsbsp_a_SOURCES += console/fbcons.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/sed1356.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/fbcons.c
endif
# umon
if ENABLE_UMON

View File

@@ -1,223 +0,0 @@
/*
* Console driver for AT91RM9200 DBGU port
*
* This driver uses the shared console driver in
* ...../libbsp/shared/console.c
*
* Copyright (c) 2003 by Cogent Computer Systems
* Written by Mike Kelly <mike@cogcomp.com>
* and Jay Monkman <jtm@lopingdog.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <rtems/libio.h>
#include <termios.h>
#include <at91rm9200.h>
#include <at91rm9200_dbgu.h>
#include <at91rm9200_pmc.h>
#include <rtems/bspIo.h>
#include <libchip/serial.h>
#include <libchip/sersupp.h>
volatile int dbg_dly;
/* static function prototypes */
static int dbgu_first_open(int major, int minor, void *arg);
static int dbgu_last_close(int major, int minor, void *arg);
static int dbgu_read(int minor);
static ssize_t dbgu_write(int minor, const char *buf, size_t len);
static void dbgu_init(int minor);
static void dbgu_write_polled(int minor, char c);
static int dbgu_set_attributes(int minor, const struct termios *t);
/* Pointers to functions for handling the UART. */
const console_fns dbgu_fns =
{
libchip_serial_default_probe,
dbgu_first_open,
dbgu_last_close,
dbgu_read,
dbgu_write,
dbgu_init,
dbgu_write_polled, /* not used in this driver */
dbgu_set_attributes,
FALSE /* TRUE if interrupt driven, FALSE if not. */
};
/*********************************************************************/
/* Functions called via callbacks (i.e. the ones in uart_fns */
/*********************************************************************/
/*
* This is called the first time each device is opened. Since
* the driver is polled, we don't have to do anything. If the driver
* were interrupt driven, we'd enable interrupts here.
*/
static int dbgu_first_open(int major, int minor, void *arg)
{
return 0;
}
/*
* This is called the last time each device is closed. Since
* the driver is polled, we don't have to do anything. If the driver
* were interrupt driven, we'd disable interrupts here.
*/
static int dbgu_last_close(int major, int minor, void *arg)
{
return 0;
}
/*
* Read one character from UART.
*
* return -1 if there's no data, otherwise return
* the character in lowest 8 bits of returned int.
*/
static int dbgu_read(int minor)
{
char c;
console_tbl *console_entry;
at91rm9200_dbgu_regs_t *dbgu;
console_entry = BSP_get_uart_from_minor(minor);
if (console_entry == NULL) {
return -1;
}
dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1;
if (!(dbgu->sr & DBGU_INT_RXRDY)) {
return -1;
}
c = dbgu->rhr & 0xff;
return c;
}
/*
* Write buffer to UART
*
* return 1 on success, -1 on error
*/
static ssize_t dbgu_write(int minor, const char *buf, size_t len)
{
int i, x;
char c;
console_tbl *console_entry;
at91rm9200_dbgu_regs_t *dbgu;
console_entry = BSP_get_uart_from_minor(minor);
if (console_entry == NULL) {
return -1;
}
dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1;
for (i = 0; i < len; i++) {
/* Wait for fifo to have room */
while(1) {
if (dbgu->sr & DBGU_INT_TXRDY) {
break;
}
}
c = (char) buf[i];
dbgu->thr = c;
/* the TXRDY flag does not seem to update right away (is this true?) */
/* so we wait a bit before continuing */
for (x = 0; x < 100; x++) {
dbg_dly++; /* using a global so this doesn't get optimized out */
}
}
return 1;
}
/* Set up the UART. */
static void dbgu_init(int minor)
{
console_tbl *console_entry;
at91rm9200_dbgu_regs_t *dbgu;
console_entry = BSP_get_uart_from_minor(minor);
if (console_entry == NULL) {
return;
}
dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1;
/* Clear error bits, and reset */
dbgu->cr = (DBGU_CR_RSTSTA | DBGU_CR_RSTTX | DBGU_CR_RSTRX);
/* Clear pending interrupts */
dbgu->idr = DBGU_INT_ALL;
dbgu->imr = 0;
/* Set port to no parity, no loopback */
dbgu->mr = DBGU_MR_PAR_NONE | DBGU_MR_CHMODE_NORM;
/* Set the baud rate */
dbgu->brgr = (at91rm9200_get_mck() / 16) / BSP_get_baud();
/* Enable the DBGU */
dbgu->cr = (DBGU_CR_TXEN | DBGU_CR_RXEN);
}
/* This is used for getchark support */
static void dbgu_write_polled(int minor, char c)
{
dbgu_write(minor, &c, 1);
}
/* This is for setting baud rate, bits, etc. */
static int dbgu_set_attributes(int minor, const struct termios *t)
{
return 0;
}
/***********************************************************************/
/*
* The following functions are not used by TERMIOS, but other RTEMS
* functions use them instead.
*/
/***********************************************************************/
/*
* Read from UART. This is used in the exit code, and can't
* rely on interrupts.
*/
static int dbgu_poll_read(int minor)
{
return dbgu_read(minor);
}
/*
* Write a character to the console. This is used by printk() and
* maybe other low level functions. It should not use interrupts or any
* RTEMS system calls. It needs to be very simple
*/
static void _BSP_put_char( char c ) {
dbgu_write_polled(0, c);
}
BSP_output_char_function_type BSP_output_char = _BSP_put_char;
static int _BSP_poll_char(void)
{
return dbgu_poll_read(0);
}
BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char;

View File

@@ -1,125 +0,0 @@
/*
* LCD Console Output Driver for CSBx37
*/
/*
* COPYRIGHT (c) 1989-2014.
* On-Line Applications Research Corporation (OAR).
*
* Modified by Fernando Nicodemos <fgnicodemos@terra.com.br>
* from NCB - Sistemas Embarcados Ltda. (Brazil)
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <rtems/libio.h>
#include <termios.h>
#include <rtems/bspIo.h>
#include <libchip/serial.h>
#include <libchip/sersupp.h>
#include "sed1356.h"
/* static function prototypes */
static int fbcons_first_open(int major, int minor, void *arg);
static int fbcons_last_close(int major, int minor, void *arg);
static int fbcons_read(int minor);
static ssize_t fbcons_write(int minor, const char *buf, size_t len);
static void fbcons_init(int minor);
static void fbcons_write_polled(int minor, char c);
static int fbcons_set_attributes(int minor, const struct termios *t);
/* Pointers to functions for handling the UART. */
const console_fns fbcons_fns =
{
libchip_serial_default_probe,
fbcons_first_open,
fbcons_last_close,
fbcons_read,
fbcons_write,
fbcons_init,
fbcons_write_polled, /* not used in this driver */
fbcons_set_attributes,
FALSE /* TRUE if interrupt driven, FALSE if not. */
};
/*********************************************************************/
/* Functions called via callbacks (i.e. the ones in uart_fns */
/*********************************************************************/
/*
* This is called the first time each device is opened. Since
* the driver is polled, we don't have to do anything. If the driver
* were interrupt driven, we'd enable interrupts here.
*/
static int fbcons_first_open(int major, int minor, void *arg)
{
/* printk( "Frame buffer -- first open\n" ); */
return 0;
}
/*
* This is called the last time each device is closed. Since
* the driver is polled, we don't have to do anything. If the driver
* were interrupt driven, we'd disable interrupts here.
*/
static int fbcons_last_close(int major, int minor, void *arg)
{
/* printk( "Frame buffer -- last close\n" ); */
return 0;
}
/*
* Read one character from UART.
*
* return -1 if there's no data, otherwise return
* the character in lowest 8 bits of returned int.
*/
static int fbcons_read(int minor)
{
/* printk( "Frame buffer -- read\n" ); */
return -1;
}
/*
* Write buffer to LCD
*
* return 1 on success, -1 on error
*/
static ssize_t fbcons_write(int minor, const char *buf, size_t len)
{
int i;
/* printk( "Frame buffer -- write\n" ); */
for ( i=0 ; i<len ; i++ )
sed_putchar( buf[i] );
return 1;
}
/* Set up the LCD controller. */
static void fbcons_init(int minor)
{
/* printk( "Initializing frame buffer\n" ); */
sed_init();
}
/* This is used for putchark support */
static void fbcons_write_polled(int minor, char c)
{
/* printk( "frame buffer -- write polled\n" ); */
sed_putchar( c );
}
/* This is for setting baud rate, bits, etc. */
static int fbcons_set_attributes(int minor, const struct termios *t)
{
/* printk( "frame buffer -- set attributes\n" ); */
return 0;
}

View File

@@ -1,461 +0,0 @@
/*
* SED1356 Support for KIT637_V6 (CSB637)
*
* Based upon code from MicroMonitor 1.17 from http://www.umonfw.com/
* which includes this notice:
*/
/*
**************************************************************************
* General notice:
* This code is part of a boot-monitor package developed as a generic base
* platform for embedded system designs. As such, it is likely to be
* distributed to various projects beyond the control of the original
* author. Please notify the author of any enhancements made or bugs found
* so that all may benefit from the changes. In addition, notification back
* to the author will allow the new user to pick up changes that may have
* been made by other users after this version of the code was distributed.
*
* Note1: the majority of this code was edited with 4-space tabs.
* Note2: as more and more contributions are accepted, the term "author"
* is becoming a mis-representation of credit.
*
* Original author: Ed Sutter
* Email: esutter@alcatel-lucent.com
* Phone: 908-582-2351
**************************************************************************
*
* Ed Sutter has been informed that this code is being used in RTEMS.
*
* This code was reformatted by Joel Sherrill from OAR Corporation and
* Fernando Nicodemos <fgnicodemos@terra.com.br> from NCB - Sistemas
* Embarcados Ltda. (Brazil) to be more compliant with RTEMS coding
* standards and to eliminate C++ style comments.
*/
#include <bsp.h>
#include <stdlib.h>
#include <stdio.h>
#include "sed1356.h"
#include "font8x16.h"
int mode900lq;
long PIXELS_PER_ROW;
long PIXELS_PER_COL;
long COLS_PER_SCREEN;
long ROWS_PER_SCREEN;
long SED_HOR_PULSE_WIDTH_LCD;
long SED_VER_PULSE_START_LCD;
long SED_HOR_PULSE_START_LCD;
long SED_HOR_NONDISP_LCD;
long SED_VER_NONDISP_LCD;
long SED_VER_PULSE_WIDTH_LCD;
/* globals to keep track of foreground, background colors and x,y position */
int sed_color_depth; /* 4, 8 or 16 */
int sed_fg_color; /* 0 to 15, used as lookup into VGA color table */
int sed_bg_color; /* 0 to 15, used as lookup into VGA color table */
int sed_col; /* current column, 0 to COLS_PER_SCREEN - 1 */
int sed_row; /* current row, 0 to (ROWS_PER_SCREEN * 2) - 1 */
int sed_disp_mode_crt; /* CRT=1, LCD=0 */
int sed135x_ok;
int sed135x_tst;
uint32_t sed_fb_offset; /* current offset into frame buffer for sed_putchar */
void sed_writechar(uint8_t c);
void sed_scroll(void);
#define SED_REG_BASE 0x30000000 /* *CS2 */
#define SED_MEM_BASE (SED_REG_BASE + 0x00200000)
#define SED_STEP 1 /* 16-bit port on 16-bit boundry */
#define SED_REG16(_x_) *(volatile uint16_t *)((uint32_t)SED_REG_BASE + (((uint32_t)_x_ * SED_STEP) ^ 0)) /* Control/Status Registers, 16-bit mode */
#define RD_FB16(_reg_,_val_) ((_val_) = *((volatile uint16_t *)(((uint32_t)SED_MEM_BASE + ((uint32_t)(_reg_ * SED_STEP) ^ 0)))))
#define WR_FB16(_reg_,_val_) (*((volatile uint16_t *)(((uint32_t)SED_MEM_BASE + ((uint32_t)(_reg_ * SED_STEP) ^ 0)))) = (_val_))
#if 0
#define SED1356_REG_LCD_HOR_DISP SED_REG16(0x32)
#define SED1356_REG_LCD_HOR_NONDISP_and_START SED_REG16(0x34)
#define SED1356_REG_LCD_HOR_PULSE SED_REG16(0x36)
#define SED1356_REG_LCD_VER_DISP_HT_LO_and_HI SED_REG16(0x38)
#define SED1356_REG_LCD_VER_NONDISP_and_START SED_REG16(0x3a)
#define SED1356_REG_LCD_VER_PULSE SED_REG16(0x3c)
#define SED1356_REG_LCD_DISP_MODE_and_MISC SED_REG16(0x40)
#define SED1356_REG_LCD_DISP_START_LO_and_MID SED_REG16(0x42)
#define SED1356_REG_LCD_DISP_START_HI SED_REG16(0x44)
#define SED1356_REG_LCD_ADD_OFFSET_LO_and_HI SED_REG16(0x46)
#define SED1356_REG_LCD_PIXEL_PAN SED_REG16(0x48)
#define SED1356_REG_LCD_FIFO_THRESH_LO_and_HI SED_REG16(0x4a)
#endif
#define H2SED(_x_) (_x_)
#define FB_SIZE (640 * 480)
#define SED_ROW_SIZE(_depth_) ((PIXELS_PER_ROW * _depth_) / 8)
#define SED_FB_SIZE(_depth_) (((PIXELS_PER_COL * PIXELS_PER_ROW) * _depth_) / 8)
#define FONT_WIDTH 8
#define FONT_HEIGHT 16
#define SED_GET_ADD(_row_, _col_, _depth_) \
(((((_row_ * PIXELS_PER_ROW) * FONT_HEIGHT) \
+ (_col_ * FONT_WIDTH)) \
* _depth_) / 8)
#define SED_GET_PHYS_ADD(_reg_) \
(volatile unsigned long)(SED_MEM_BASE + ((_reg_ * SED_STEP) ^ 0))
#include "sed1356_16bit.h"
/* #define SED_DBG */
int sed135x_tst = 0;
void sed_write_frame_buffer(
uint32_t i,
uint16_t wr16
)
{
WR_FB16(i, wr16);
}
int sed_frame_buffer_size(void)
{
return SED_FB_SIZE(sed_color_depth);
}
void sed_clr_row(int char_row)
{
unsigned long sed_mem_add;
int i;
uint16_t wr16;
/* clear the desired row */
sed_mem_add = SED_GET_ADD(char_row, 0, sed_color_depth);
#ifdef SED_DBG
sed135x_tst = 1;
printf("SED Clear Row %d, FB Add 0x%08lx, CPU Add 0x%08lx.\n ", char_row, sed_mem_add, SED_GET_PHYS_ADD(sed_mem_add));
sed135x_tst = 0;
#endif
switch (sed_color_depth)
{
case 4:
wr16 = ((sed_bg_color << 12) | (sed_bg_color << 8) | (sed_bg_color << 4) | (sed_bg_color << 0));
#ifdef SED_DBG
sed135x_tst = 1;
printf("SED Clear Row %d, FB Add 0x%08lx to 0x%08lx.\n ", char_row, sed_mem_add, sed_mem_add + ((PIXELS_PER_ROW * FONT_HEIGHT) / 2));
sed135x_tst = 0;
#endif
for (i = 0; i < ((PIXELS_PER_ROW * FONT_HEIGHT) / 2); i += 2){
WR_FB16(sed_mem_add, wr16);
sed_mem_add += 2;
} /* for font_row */
break;
case 8:
wr16 = ((sed_bg_color << 8) | (sed_bg_color << 0));
for (i = 0; i < (PIXELS_PER_ROW * FONT_HEIGHT); i += 2){
WR_FB16(sed_mem_add, wr16);
sed_mem_add += 2;
} /* for font_row */
break;
case 16:
wr16 = ((vga_lookup[sed_bg_color]));
for (i = 0; i < ((PIXELS_PER_ROW * FONT_HEIGHT) * 2); i += 2){
WR_FB16(sed_mem_add, wr16);
sed_mem_add += 2;
} /* for font_row */
break;
} /* switch sed_color_depth */
} /* sed_clr_row */
void sed_init(void)
{
mode900lq = 0;
PIXELS_PER_ROW = 640;
PIXELS_PER_COL = 480;
COLS_PER_SCREEN = 80;
ROWS_PER_SCREEN = 30;
SED_HOR_PULSE_WIDTH_LCD = 0x0b;
SED_HOR_NONDISP_LCD = 0x13;
SED_VER_PULSE_WIDTH_LCD = 0x01;
SED_VER_PULSE_START_LCD = 0x09;
SED_VER_NONDISP_LCD = 0x2c;
sed_color_depth = 16; /* 16 => vga lookup */
sed_fg_color = 14; /* Bright Yellow */
sed_bg_color = 1; /* Blue */
sed_disp_mode_crt = 0; /* default to LCD */
sed_fb_offset = 0x00;
sed_row = 0;
sed_col = 0;
sed135x_ok = 1;
sed135x_tst = 0;
sed_clearscreen();
}
/*
* sed_putchar()
*
* This routine parses the character and calls sed_writechar if it is a
* printable character
*/
void sed_putchar(char c)
{
if ((sed135x_ok == 0) || (sed135x_tst == 1)) return;
/* First parse the character to see if it printable or an
* acceptable control character.
*/
switch (c) {
case '\r':
sed_col = 0;
return;
case '\n':
sed_col = 0;
sed_scroll();
return;
case '\b':
sed_col--;
if (sed_col < 0) {
sed_row--;
if (sed_row < 0)
sed_row = 0;
sed_col = COLS_PER_SCREEN - 1;
}
c = 0; /* erase the character */
sed_writechar(c);
break;
default:
if (((uint8_t)c < FIRST_CHAR) || ((uint8_t)c > LAST_CHAR))
return; /* drop anything we can't print */
c -= FIRST_CHAR; /* get aligned to the first printable character */
sed_writechar(c);
/* advance to next column */
sed_col++;
if (sed_col == COLS_PER_SCREEN) {
sed_col = 0;
sed_scroll();
}
break;
}
} /* sed_putchar() */
/*
* sed_writechar()
*
* This routine writes the character to the screen at the current cursor
* location.
*/
void sed_writechar(uint8_t c)
{
uint32_t sed_mem_add;
int font_row, font_col;
uint8_t font_data8;
uint16_t wr16;
/* Convert the current row,col and color depth values
* into an address
*/
sed_mem_add = SED_GET_ADD(sed_row, sed_col, sed_color_depth);
#ifdef SED_DBG
sed135x_tst = 1;
printf("SED writechar at row %d, col %d, FB Add 0x%08lx, CPU Add 0x%08lx.\n ", sed_row, sed_col, sed_mem_add, SED_GET_PHYS_ADD(sed_mem_add));
sed135x_tst = 0;
#endif
if (FONT_WIDTH == 8) {
switch (sed_color_depth) {
case 4:
/* Now render the font by painting one font row at a time */
for (font_row = 0; font_row < FONT_HEIGHT; font_row++) {
/* get the font row of data */
font_data8 = font8x16[(c * FONT_HEIGHT) + font_row];
for (font_col = 0; font_col < 8; font_col += 4)
{
/* get a words worth of pixels */
wr16 = (((font_data8 & 0x80) ? sed_fg_color << 12 : sed_bg_color << 12)
| ((font_data8 & 0x40) ? sed_fg_color << 8 : sed_bg_color << 8)
| ((font_data8 & 0x20) ? sed_fg_color << 4 : sed_bg_color << 4)
| ((font_data8 & 0x10) ? sed_fg_color << 0 : sed_bg_color << 0));
font_data8 = font_data8 << 4;
WR_FB16(sed_mem_add, wr16);
/* if we are in the 2nd frame buffer, write to the 1st
* frame buffer also
*/
if (sed_row > (ROWS_PER_SCREEN - 1)) {
WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16);
}
sed_mem_add += 2;
} /* for font_col */
/* go to the next pixel row */
sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8));
} /* for font_row */
break;
case 8:
/* Now render the font by painting one font row at a time */
for (font_row = 0; font_row < FONT_HEIGHT; font_row++) {
/* get the font row of data */
font_data8 = font8x16[(c * FONT_HEIGHT) + font_row];
for (font_col = 0; font_col < 8; font_col += 2)
{
/* get a words worth of pixels */
wr16 = (((font_data8 & 0x80) ? sed_fg_color << 8 : sed_bg_color << 8)
| ((font_data8 & 0x40) ? sed_fg_color << 0 : sed_bg_color << 0));
font_data8 = font_data8 << 2;
WR_FB16(sed_mem_add, wr16);
/* if we are in the 2nd frame buffer, write to the 1st
* frame buffer also
*/
if (sed_row > (ROWS_PER_SCREEN - 1)) {
WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16);
}
sed_mem_add += 2;
} /* for font_col */
/* go to the next pixel row */
sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8));
} /* for font_row */
break;
case 16:
/* Now render the font by painting one font row at a time */
for (font_row = 0; font_row < FONT_HEIGHT; font_row++) {
/* get the font row of data */
font_data8 = font8x16[(c * FONT_HEIGHT) + font_row];
for (font_col = 0; font_col < 8; font_col++)
{
/* get a words worth of pixels */
wr16 = ((font_data8 & 0x80) ?
vga_lookup[sed_fg_color] : vga_lookup[sed_bg_color]);
font_data8 = font_data8 << 1;
WR_FB16(sed_mem_add, wr16);
/* if we are in the 2nd frame buffer, write to the 1st
* frame buffer also.
*/
if (sed_row > (ROWS_PER_SCREEN - 1)) {
WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16);
}
sed_mem_add += 2;
} /* for font_col */
/* go to the next pixel row */
sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8));
} /* for font_row */
break;
} /* switch sed_color depth */
} /* FONT_WIDTH == 8 */
else
{
return;
}
} /* sed_writechar() */
static void sed_update_fb_offset(void)
{
/* write the new sed_fb_offset value */
if (sed_disp_mode_crt) {
/* before we change the address offset, wait for the display to
* go from active to non-active, unless the display is not enabled
*/
if (SED1356_REG_DISP_MODE & H2SED(SED1356_DISP_MODE_CRT)) { /* CRT is on */
while ((SED1356_REG_CRT_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 0) {}
while ((SED1356_REG_CRT_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 1) {}
}
SED1356_REG_CRT_DISP_START_LO_and_MID = H2SED(((sed_fb_offset & 0x00ffff) >> 0));
SED1356_REG_CRT_DISP_START_HI = H2SED(((sed_fb_offset & 0x070000) >> 16));
}
else /* LCD */
{
if (SED1356_REG_DISP_MODE & H2SED(SED1356_DISP_MODE_LCD)) { /* LCD is on */
while ((SED1356_REG_LCD_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 0) {}
while ((SED1356_REG_LCD_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 1) {}
}
SED1356_REG_LCD_DISP_START_LO_and_MID = H2SED(((sed_fb_offset & 0x00ffff) >> 0));
SED1356_REG_LCD_DISP_START_HI = H2SED(((sed_fb_offset & 0x070000) >> 16));
}
}
/* sed_scroll()
*
* Because we are most likely running out of FLASH and probably also with
* cache disabled, a brute force memcpy of the whole screen would be very
* slow, even with reduced color depths. Instead, we define a frame buffer
* that is twice the size of our actual display. This does limit us to a
* 1Mbyte active display size, but 640 x 480 @ 16-bits/pixel = 614K so it
* works just fine. 800 x 600 can be had by reducing the color depth to
* 8-bits/pixel and using the look up tables.
*
* With the double buffering, we always write to the first buffer, even
* when the second buffer is active. This allows us to scroll by adjusting
* the starting and ending addresses in the SED135x by one row. When we
* reach the end of our virtual buffer, we reset the starting and ending
* addresses to the first buffer. Note that we can not adjust the SED135x
* registers until it is in vertical retrace. That means we have to wait
* until it is in active display, then goes to non-display, unless the
* screen is blanked, in which case we can update immediately.
*/
void sed_scroll(void)
{
sed_row++;
/* clear the new row(s) */
sed_clr_row(sed_row);
if (sed_row > (ROWS_PER_SCREEN - 1)) {
sed_clr_row(sed_row - ROWS_PER_SCREEN);
}
/* when sed_y_pos is greater than ROWS_PER_SCREEN we just adjust the
* start and end addresses in the SED135x. If it is equal to 2 *
* ROWS_PER_SCREEN, we reset the start and end addresses to SED_MEM_BASE.
*/
if (sed_row > (ROWS_PER_SCREEN - 1)) {
if (sed_row > ((ROWS_PER_SCREEN * 2) - 1)) {
sed_fb_offset = 0x00;
sed_row = 0;
sed_clearscreen();
} else {
/* calculate the new offset address of the frame buffer in words */
sed_fb_offset += (SED_GET_ADD(1, 0, sed_color_depth) / 2);
}
sed_update_fb_offset();
} /* if (sed_row > (ROWS_PER_SCREEN - 1)) */
}
void sed_putstring(char *s)
{
char *p = s;
while (*p)
sed_putchar(*p++);
}
void sed_clearscreen(void)
{
int i;
uint16_t wr16;
int bg = sed_bg_color;
int fbsize = sed_frame_buffer_size();
/* we double buffer so clear ALL of memory */
fbsize *= 2;
/* fill the frame buffer with incrementing color values */
switch (sed_color_depth){
case 4: wr16 = bg | bg << 4 | bg << 8 | bg << 12; break;
case 8: wr16 = bg | bg << 8; break;
/* 16-bits bypasses the lookup table */
default: wr16 = vga_lookup[bg]; break;
}
for (i = 0; i < fbsize; i += 2){
sed_write_frame_buffer(i, wr16);
}
}

View File

@@ -1,243 +0,0 @@
/*
* Console driver for for KIT637_V6 (CSB637)
*
* This driver uses the shared console driver in
* ...../libbsp/shared/console.c
*
* Copyright (c) 2003 by Cogent Computer Systems
* Written by Jay Monkman <jtm@lopingdog.com>
*
* Modified by Fernando Nicodemos <fgnicodemos@terra.com.br>
* from NCB - Sistemas Embarcados Ltda. (Brazil)
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Modified and FrameBuffer Console Device Support added by
* Joel Sherrill, 2009.
*/
#include <bsp.h>
#include <rtems/libio.h>
#include <termios.h>
#include <rtems/bspIo.h>
#include <at91rm9200.h>
#include <at91rm9200_dbgu.h>
#include <libchip/serial.h>
#include <libchip/sersupp.h>
#include <bspopts.h>
extern const console_fns dbgu_fns;
#if ENABLE_LCD
extern const console_fns fbcons_fns;
#define LCD_DEV 1
#else
#define LCD_DEV 0
#endif
#if (ENABLE_UMON && ENABLE_UMON_CONSOLE)
extern const console_fns umoncons_fns;
#define UMON_CONS_DEV 1
#else
#define UMON_CONS_DEV 0
#endif
#if ENABLE_USART0 || ENABLE_USART1 || ENABLE_USART2 || ENABLE_USART3
extern const console_fns usart_polling_fns;
#endif
#if ENABLE_USART0
#define USART0_DEV 1
#else
#define USART0_DEV 0
#endif
#if ENABLE_USART1
#define USART1_DEV 1
#else
#define USART1_DEV 0
#endif
#if ENABLE_USART2
#define USART2_DEV 1
#else
#define USART2_DEV 0
#endif
#if ENABLE_USART3
#define USART3_DEV 1
#else
#define USART3_DEV 0
#endif
#define NUM_DEVS \
(1 + LCD_DEV + UMON_CONS_DEV + \
USART0_DEV + USART1_DEV + USART2_DEV + USART3_DEV)
/* These are used by code in console.c */
unsigned long Console_Configuration_Count = NUM_DEVS;
/*
* There's one item in array for each UART.
*
* Some of these fields are marked "NOT USED". They are not used
* by console.c, but may be used by drivers in libchip
*
* when we add other types of UARTS we will need to move this
* structure to a generic uart.c file with only this in it
*/
console_tbl Console_Configuration_Ports[] = {
{
"/dev/com0", /* sDeviceName */
SERIAL_CUSTOM, /* deviceType */
&dbgu_fns, /* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
0, /* ulMargin - NOT USED */
0, /* ulHysteresis - NOT USED */
NULL, /* pDeviceParams */
DBGU_BASE, /* ulCtrlPort1 - Pointer to DBGU regs */
0, /* ulCtrlPort2 - NOT USED */
0, /* ulDataPort - NOT USED */
NULL, /* getRegister - NOT USED */
NULL, /* setRegister - NOT USED */
NULL, /* getData - NOT USED */
NULL, /* setData - NOT USED */
0, /* ulClock - NOT USED */
0 /* ulIntVector - NOT USED */
},
#if ENABLE_LCD
{
"/dev/fbcons", /* sDeviceName */
SERIAL_CUSTOM, /* deviceType */
&fbcons_fns, /* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
0, /* ulMargin - NOT USED */
0, /* ulHysteresis - NOT USED */
NULL, /* pDeviceParams */
0, /* ulCtrlPort1 - Pointer to DBGU regs */
0, /* ulCtrlPort2 - NOT USED */
0, /* ulDataPort - NOT USED */
NULL, /* getRegister - NOT USED */
NULL, /* setRegister - NOT USED */
NULL, /* getData - NOT USED */
NULL, /* setData - NOT USED */
0, /* ulClock - NOT USED */
0 /* ulIntVector - NOT USED */
},
#endif
#if (ENABLE_UMON && ENABLE_UMON_CONSOLE)
{
"/dev/umon", /* sDeviceName */
SERIAL_CUSTOM, /* deviceType */
&umoncons_fns, /* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
0, /* ulMargin - NOT USED */
0, /* ulHysteresis - NOT USED */
NULL, /* pDeviceParams */
0, /* ulCtrlPort1 - Pointer to UMON regs */
0, /* ulCtrlPort2 - NOT USED */
0, /* ulDataPort - NOT USED */
NULL, /* getRegister - NOT USED */
NULL, /* setRegister - NOT USED */
NULL, /* getData - NOT USED */
NULL, /* setData - NOT USED */
0, /* ulClock - NOT USED */
0 /* ulIntVector - NOT USED */
},
#endif
#if ENABLE_USART0
{
"/dev/com1", /* sDeviceName */
SERIAL_CUSTOM, /* deviceType */
&usart_polling_fns,/* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
0, /* ulMargin - NOT USED */
0, /* ulHysteresis - NOT USED */
NULL, /* pDeviceParams */
USART0_BASE, /* ulCtrlPort1 - Pointer to USART 0 regs */
0, /* ulCtrlPort2 - NOT USED */
0, /* ulDataPort - NOT USED */
NULL, /* getRegister - NOT USED */
NULL, /* setRegister - NOT USED */
NULL, /* getData - NOT USED */
NULL, /* setData - NOT USED */
0, /* ulClock - NOT USED */
0 /* ulIntVector - NOT USED */
},
#endif
#if ENABLE_USART1
{
"/dev/com2", /* sDeviceName */
SERIAL_CUSTOM, /* deviceType */
&usart_polling_fns,/* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
0, /* ulMargin - NOT USED */
0, /* ulHysteresis - NOT USED */
NULL, /* pDeviceParams */
USART1_BASE, /* ulCtrlPort1 - Pointer to USART 1 regs */
0, /* ulCtrlPort2 - NOT USED */
0, /* ulDataPort - NOT USED */
NULL, /* getRegister - NOT USED */
NULL, /* setRegister - NOT USED */
NULL, /* getData - NOT USED */
NULL, /* setData - NOT USED */
0, /* ulClock - NOT USED */
0 /* ulIntVector - NOT USED */
},
#endif
#if ENABLE_USART2
{
"/dev/com3", /* sDeviceName */
SERIAL_CUSTOM, /* deviceType */
&usart_polling_fns,/* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
0, /* ulMargin - NOT USED */
0, /* ulHysteresis - NOT USED */
NULL, /* pDeviceParams */
USART2_BASE, /* ulCtrlPort1 - Pointer to USART 2 regs */
0, /* ulCtrlPort2 - NOT USED */
0, /* ulDataPort - NOT USED */
NULL, /* getRegister - NOT USED */
NULL, /* setRegister - NOT USED */
NULL, /* getData - NOT USED */
NULL, /* setData - NOT USED */
0, /* ulClock - NOT USED */
0 /* ulIntVector - NOT USED */
},
#endif
#if ENABLE_USART3
{
"/dev/com4", /* sDeviceName */
SERIAL_CUSTOM, /* deviceType */
&usart_polling_fns,/* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
0, /* ulMargin - NOT USED */
0, /* ulHysteresis - NOT USED */
NULL, /* pDeviceParams */
USART3_BASE, /* ulCtrlPort1 - Pointer to USART 3 regs */
0, /* ulCtrlPort2 - NOT USED */
0, /* ulDataPort - NOT USED */
NULL, /* getRegister - NOT USED */
NULL, /* setRegister - NOT USED */
NULL, /* getData - NOT USED */
NULL, /* setData - NOT USED */
0, /* ulClock - NOT USED */
0 /* ulIntVector - NOT USED */
}
#endif
};
console_tbl *BSP_get_uart_from_minor(int minor)
{
return Console_Port_Tbl[minor];
}

View File

@@ -1,261 +0,0 @@
/*
* Driver for AT91RM9200 USART ports
*/
/*
* COPYRIGHT (c) 2006-2009.
* NCB - Sistemas Embarcados Ltda. (Brazil)
* Fernando Nicodemos <fgnicodemos@terra.com.br>
*
* and
*
* COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <rtems/libio.h>
#include <termios.h>
#include <at91rm9200.h>
#include <at91rm9200_usart.h>
#include <at91rm9200_pmc.h>
#include <rtems/bspIo.h>
#include <libchip/serial.h>
#include <libchip/sersupp.h>
/* static function prototypes */
static int usart_first_open(int major, int minor, void *arg);
static int usart_last_close(int major, int minor, void *arg);
static int usart_read_polled(int minor);
static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len);
static void usart_init(int minor);
static void usart_write_polled(int minor, char c);
static int usart_set_attributes(int minor, const struct termios *t);
at91rm9200_usart_regs_t *usart_get_base(int minor);
/* Pointers to functions for handling the UART polled. */
const console_fns usart_polling_fns = {
libchip_serial_default_probe, /* deviceProbe */
usart_first_open, /* deviceFirstOpen */
usart_last_close, /* deviceLastClose */
usart_read_polled, /* deviceRead */
usart_write_polled_support, /* deviceWrite */
usart_init, /* deviceInitialize */
usart_write_polled, /* deviceWritePolled */
usart_set_attributes, /* deviceSetAttributes */
FALSE /* TRUE if interrupt driven, FALSE if not. */
};
at91rm9200_usart_regs_t *usart_get_base(int minor)
{
console_tbl *console_entry;
at91rm9200_usart_regs_t *port;
console_entry = BSP_get_uart_from_minor(minor);
if (console_entry == NULL)
return 0;
port = (at91rm9200_usart_regs_t *) console_entry->ulCtrlPort1;
//printk( "minor=%d entry=%p port=%p\n", minor, console_entry, port );
return port;
}
/*
* Functions called via callbacks (i.e. the ones in uart_fns
*/
/*
* This is called the first time each device is opened. Since
* the driver is polled, we don't have to do anything. If the driver
* were interrupt driven, we'd enable interrupts here.
*/
static int usart_first_open(int major, int minor, void *arg)
{
at91rm9200_usart_regs_t *usart;
usart = usart_get_base(minor);
if ( !usart )
return -1;
/* XXX port isn't being initialized or enabled */
/* XXX I hope this is enough */
usart->cr = (US_CR_RXEN | US_CR_TXEN);
return 0;
}
/*
* This is called the last time each device is closed. Since
* the driver is polled, we don't have to do anything. If the driver
* were interrupt driven, we'd disable interrupts here.
*/
static int usart_last_close(int major, int minor, void *arg)
{
at91rm9200_usart_regs_t *usart;
usart = usart_get_base(minor);
if ( !usart )
return -1;
return 0;
}
/*
* Read one character from UART.
*
* return -1 if there's no data, otherwise return
* the character in lowest 8 bits of returned int.
*/
static int usart_read_polled(int minor)
{
at91rm9200_usart_regs_t *usart;
usart = usart_get_base(minor);
if ( !usart )
return -1;
/* if nothing ready return -1 */
if ( (usart->sr & US_IER_RXRDY) == 0 )
return -1;
return usart->rhr;
}
/*
* Write character out
*/
static void usart_write_polled(int minor, char c)
{
at91rm9200_usart_regs_t *usart;
usart = usart_get_base(minor);
if ( !usart )
return;
/* delay until TX empty */
while ( (usart->sr & US_IER_TXEMPTY) == 0 )
;
usart->thr = c;
}
/*
* Write buffer to UART
*
* return 1 on success, -1 on error
*/
static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len)
{
at91rm9200_usart_regs_t *usart;
int nwrite=0;
/*
* Verify the minor number
*/
usart = usart_get_base(minor);
if ( !usart )
return -1;
/*
* poll each byte in the string out of the port.
*/
while (nwrite < len) {
usart_write_polled(minor, *buf++);
nwrite++;
}
/*
* return the number of bytes written.
*/
return nwrite;
return 1;
}
/* Set up the UART. */
static void usart_init(int minor)
{
at91rm9200_usart_regs_t *usart;
usart = usart_get_base(minor);
if ( !usart )
return;
}
/* This is for setting baud rate, bits, etc. */
static int usart_set_attributes(int minor, const struct termios *t)
{
uint32_t brgr;
uint32_t mode, baud, baud_requested;
at91rm9200_usart_regs_t *usart;
usart = usart_get_base(minor);
if ( !usart )
return -1;
/* Get current mode register */
mode = usart->mr & ~(US_MR_USMODE | US_MR_USCLKS | US_MR_CHRL
| US_MR_PAR | US_MR_NBSTOP);
/* Byte size */
switch (t->c_cflag & CSIZE){
case CS5:
mode |= US_MR_CHRL_5;
break;
case CS6:
mode |= US_MR_CHRL_6;
break;
case CS7:
mode |= US_MR_CHRL_7;
break;
default:
mode |= US_MR_CHRL_8;
break;
}
/* Stop bits */
if (t->c_cflag & CSTOPB){
mode |= US_MR_NBSTOP_2; /* 2 stop bits */
} else
mode |= US_MR_NBSTOP_1; /* 1 stop bits */
/* Parity */
if (t->c_cflag & PARENB){
/* Mark or Space parity */
if (t->c_cflag & PARODD){
mode |= US_MR_PAR_ODD;
} else
mode |= US_MR_PAR_EVEN;
} else
mode |= US_MR_PAR_NONE;
baud_requested = t->c_ospeed;
/* If not, set the dbgu console baud as USART baud default */
if (!baud_requested)
baud_requested = BSP_get_baud();
baud = rtems_termios_baud_to_number(baud_requested);
brgr = (at91rm9200_get_mck() / 16) / baud;
if (brgr > 65535){ /* BRGR is 16-bit, so switch to slower clock */
brgr /= 8;
mode |= US_MR_USCLKS_MCK_DIV8;
}
usart->mr = mode;
usart->brgr = brgr;
return 0;
}

View File

@@ -32,7 +32,7 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/edb7312/clock/clockdrv.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
librtemsbsp_a_SOURCES += console/uart.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/edb7312/console/uart.c
# timer
librtemsbsp_a_SOURCES += timer/timer.c

View File

@@ -1,169 +0,0 @@
/*
* Cirrus EP7312 Console Driver
*
* Copyright (c) 2002 by Jay Monkman <jtm@smoothsmoothie.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h> /* Must be before libio.h */
#include <rtems/libio.h>
#include <termios.h>
#include <rtems/bspIo.h>
#include <ep7312.h>
#include <libchip/serial.h>
#include <libchip/sersupp.h>
#define NUM_DEVS 1
int uart_poll_read(int minor);
static int uart_first_open(int major, int minor, void *arg);
static int uart_last_close(int major, int minor, void *arg);
static int uart_read(int minor);
static ssize_t uart_write(int minor, const char *buf, size_t len);
static void uart_init(int minor);
static void uart_write_polled(int minor, char c);
static int uart_set_attributes(int minor, const struct termios *t);
unsigned long Console_Configuration_Count = NUM_DEVS;
const console_fns uart_fns =
{
libchip_serial_default_probe,
uart_first_open,
uart_last_close,
uart_read,
uart_write,
uart_init,
uart_write_polled,
uart_set_attributes,
FALSE
};
console_tbl Console_Configuration_Ports[] = {
{
"/dev/com0", /* sDeviceName */
SERIAL_CUSTOM, /* deviceType */
&uart_fns, /* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
16, /* ulMargin */
8, /* ulHysteresis */
NULL, /* pDeviceParams */
(uint32_t)EP7312_UARTCR1, /* ulCtrlPort1 */
(uint32_t)EP7312_SYSFLG1, /* ulCtrlPort2 */
(uint32_t)EP7312_UARTDR1, /* ulDataPort */
0, /* getRegister */
0, /* setRegister */
0, /* getData */
0, /* setData */
0, /* ulClock */
0 /* ulIntVector */
}};
static int uart_first_open(int major, int minor, void *arg) {return 0;}
static int uart_last_close(int major, int minor, void *arg) {return 0;}
static int uart_read(int minor)
{
return uart_poll_read(minor);
}
static void uart_write_polled(int minor, char c)
{
uart_write(minor, &c, 1);
}
static int uart_set_attributes(int minor, const struct termios *t)
{
return 0;
}
int uart_poll_read(int minor)
{
volatile uint32_t *data_reg;
volatile uint32_t *ctrl_reg2;
char c;
int err;
data_reg = (uint32_t *)Console_Port_Tbl[minor]->ulDataPort;
ctrl_reg2 = (uint32_t *)Console_Port_Tbl[minor]->ulCtrlPort2;
if ((*ctrl_reg2 & EP7312_UART_URXFE1) != 0) {
return -1;
}
err = *data_reg;
c = err & 0xff;
err &= (EP7312_UART_FRMERR | EP7312_UART_PARERR | EP7312_UART_OVERR);
return c;
}
static ssize_t uart_do_write(
volatile uint32_t *uartdr,
const char *buf,
size_t len,
volatile uint32_t *sysflg
)
{
size_t i;
for (i = 0; i < len; i++) {
/* Wait for fifo to have room */
while ((*sysflg & EP7312_UART_UTXFF1) != 0) {
continue;
}
*uartdr = buf[i];
}
return len;
}
static ssize_t uart_write(int minor, const char *buf, size_t len)
{
volatile uint32_t *data_reg;
volatile uint32_t *ctrl_reg2;
data_reg = (uint32_t *)Console_Port_Tbl[minor]->ulDataPort;
ctrl_reg2 = (uint32_t *)Console_Port_Tbl[minor]->ulCtrlPort2;
return uart_do_write(data_reg, buf, len, ctrl_reg2);
}
static void uart_init(int minor)
{
volatile uint32_t *ctrl_reg1;
ctrl_reg1 = (uint32_t *)Console_Port_Tbl[minor]->ulCtrlPort1;
/* *ctrl_reg = (BSP_UART_DATA8 |
BSP_UART_STOP1 |
BSP_UART_PARITY_NONE |
EP7312_UART_FIFOEN |
BSP_UART_BAUD_9600);
*/
*ctrl_reg1 = (EP7312_UART_WRDLEN8 |
EP7312_UART_FIFOEN |
0x17); /* 9600 baud */
}
/*
* Debug IO support
*/
static void _BSP_null_char(char c)
{
uart_do_write(EP7312_UARTDR1, &c, 1, EP7312_SYSFLG1);
}
static int _BSP_get_char(void)
{
return uart_poll_read(0);
}
BSP_output_char_function_type BSP_output_char = _BSP_null_char;
BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;

View File

@@ -28,8 +28,8 @@ librtemsbsp_a_SOURCES += startup/syscalls.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/cpucounter/cpucounterread.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/cpucounter/cpucounterdiff.c
# console
librtemsbsp_a_SOURCES += ../../shared/console-polled.c
librtemsbsp_a_SOURCES += console/console-io.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/gdbarmsim/console/console-io.c
# clock
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/clock/clock-simidle.c
# timer

View File

@@ -1,58 +0,0 @@
/*
* COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <bsp/console-polled.h>
#include <rtems/libio.h>
#include <stdlib.h>
#include <assert.h>
/*
* console_initialize_hardware
*
* This routine initializes the console hardware.
*
*/
void console_initialize_hardware(void)
{
return;
}
/*
* console_outbyte_polled
*
* This routine transmits a character using polling.
*/
void console_outbyte_polled(
int port,
char ch
)
{
gdbarmsim_writec(ch);
}
/*
* console_inbyte_nonblocking
*
* This routine polls for a character.
*/
int console_inbyte_nonblocking(
int port
)
{
return -1;
}
#include <rtems/bspIo.h>
static void MyBSP_output_char(char c) { console_outbyte_polled( 0, c ); }
BSP_output_char_function_type BSP_output_char = MyBSP_output_char;
BSP_polling_getchar_function_type BSP_poll_char = NULL;

View File

@@ -33,8 +33,8 @@ librtemsbsp_a_SOURCES += timer/timer.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
librtemsbsp_a_SOURCES += console/uarts.c
librtemsbsp_a_SOURCES += console/ffuart.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/gumstix/console/uarts.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/gumstix/console/ffuart.c
# IRQ
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
librtemsbsp_a_SOURCES += irq/irq.c

View File

@@ -1,227 +0,0 @@
/*
* Console driver for pxa255 full function port by Yang Xi <hiyangxi@gmail.com>
* Copyright (c) 2004 by Jay Monkman <jtm@lopingdog.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <rtems/libio.h>
#include <termios.h>
#include <pxa255.h>
#include <ffuart.h>
#include <rtems/bspIo.h>
#include <libchip/serial.h>
#include <libchip/sersupp.h>
volatile int dbg_dly;
/* static function prototypes */
static int ffuart_first_open(int major, int minor, void *arg);
static int ffuart_last_close(int major, int minor, void *arg);
static int ffuart_read(int minor);
static ssize_t ffuart_write(int minor, const char *buf, size_t len);
static void ffuart_init(int minor);
static void ffuart_write_polled(int minor, char c);
static int ffuart_set_attributes(int minor, const struct termios *t);
/* Pointers to functions for handling the UART. */
const console_fns ffuart_fns =
{
libchip_serial_default_probe,
ffuart_first_open,
ffuart_last_close,
ffuart_read,
ffuart_write,
ffuart_init,
ffuart_write_polled, /* not used in this driver */
ffuart_set_attributes,
FALSE /* TRUE if interrupt driven, FALSE if not. */
};
/*
* This is called the first time each device is opened. Since
* the driver is polled, we don't have to do anything. If the driver
* were interrupt driven, we'd enable interrupts here.
*/
static int ffuart_first_open(int major, int minor, void *arg)
{
return 0;
}
/*
* This is called the last time each device is closed. Since
* the driver is polled, we don't have to do anything. If the driver
* were interrupt driven, we'd disable interrupts here.
*/
static int ffuart_last_close(int major, int minor, void *arg)
{
return 0;
}
/*
* Read one character from UART.
*
* return -1 if there's no data, otherwise return
* the character in lowest 8 bits of returned int.
*/
static int ffuart_read(int minor)
{
char c;
console_tbl *console_entry;
ffuart_reg_t *ffuart;
console_entry = BSP_get_uart_from_minor(minor);
if (console_entry == NULL) {
return -1;
}
ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1;
if (!(ffuart->lsr & FULL_RECEIVE)) {
return -1;
}
c = ffuart->rbr & 0xff;
return c;
}
/*
* Write buffer to UART
*
* return 1 on success, -1 on error
*/
static ssize_t ffuart_write(int minor, const char *buf, size_t len)
{
size_t i, x;
char c;
console_tbl *console_entry;
ffuart_reg_t *ffuart;
console_entry = BSP_get_uart_from_minor(minor);
if (console_entry == NULL) {
return -1;
}
ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1;
for (i = 0; i < len; i++) {
while(1) {
if (ffuart->lsr & SEND_EMPTY) {
break;
}
}
c = (char) buf[i];
#if ON_SKYEYE != 1
if(c=='\n'){
ffuart->rbr = '\r';
for (x = 0; x < 100; x++) {
dbg_dly++; /* using a global so this doesn't get optimized out */
}
while(1){
if(ffuart->lsr & SEND_EMPTY){
break;
}
}
}
#endif
ffuart->rbr = c;
/* the TXRDY flag does not seem to update right away (is this true?) */
/* so we wait a bit before continuing */
for (x = 0; x < 100; x++) {
dbg_dly++; /* using a global so this doesn't get optimized out */
}
}
return 1;
}
static void ffuart_init(int minor)
{
console_tbl *console_entry;
ffuart_reg_t *ffuart;
unsigned int divisor;
console_entry = BSP_get_uart_from_minor(minor);
if (console_entry == NULL) {
return;
}
ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1;
ffuart->lcr |= DLAB;
/*Set the Bound*/
ffuart->lcr |= DLAB;
divisor = FREQUENCY_UART / (115200*16);
ffuart->rbr = divisor & 0xff;
ffuart->ier = (divisor >> 8)&0xff;
/*Disable FIFO*/
ffuart->iir = 0;
ffuart->lcr &=~DLAB;
/*Enable UART*/
ffuart->ier = 0x40;
ffuart->lcr = EIGHT_BITS_NOPARITY_1STOPBIT;
}
/* I'm not sure this is needed for the shared console driver. */
static void ffuart_write_polled(int minor, char c)
{
ffuart_write(minor, &c, 1);
}
/* This is for setting baud rate, bits, etc. */
static int ffuart_set_attributes(int minor, const struct termios *t)
{
return 0;
}
/***********************************************************************/
/*
* The following functions are not used by TERMIOS, but other RTEMS
* functions use them instead.
*/
/***********************************************************************/
/*
* Read from UART. This is used in the exit code, and can't
* rely on interrupts.
*/
static int ffuart_poll_read(int minor)
{
return ffuart_read(minor);
}
/*
* Write a character to the console. This is used by printk() and
* maybe other low level functions. It should not use interrupts or any
* RTEMS system calls. It needs to be very simple
*/
static void _BSP_put_char( char c ) {
ffuart_write_polled(0, c);
}
static int _BSP_poll_char(void) {
return ffuart_poll_read(0);
}
BSP_output_char_function_type BSP_output_char = _BSP_put_char;
BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char;

View File

@@ -1,66 +0,0 @@
/*
* Console driver for GUMSTIX by Yang Xi <hiyangxi@gmail.com>
*
* This driver uses the shared console driver in
* ...../libbsp/shared/console.c
*
* Copyright (c) 2003 by Cogent Computer Systems
* Written by Jay Monkman <jtm@lopingdog.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <rtems/libio.h>
#include <termios.h>
#include <rtems/bspIo.h>
#include <pxa255.h>
#include <libchip/serial.h>
#include <libchip/sersupp.h>
/* How many serial ports? */
#define NUM_DEVS 1
/* These are used by code in console.c */
unsigned long Console_Configuration_Count = NUM_DEVS;
extern const console_fns ffuart_fns;
/*
* There's one item in array for each UART.
*
* Some of these fields are marked "NOT USED". They are not used
* by console.c, but may be used by drivers in libchip
*
* when we add other types of UARTS we will need to move this
* structure to a generic uart.c file with only this in it
*/
console_tbl Console_Configuration_Ports[] = {
{
"/dev/com0", /* sDeviceName */
SERIAL_CUSTOM, /* deviceType */
&ffuart_fns, /* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
0, /* ulMargin - NOT USED */
0, /* ulHysteresis - NOT USED */
NULL, /* pDeviceParams */
FFUART_BASE, /* ulCtrlPort1 - Pointer to DBGU regs */
0, /* ulCtrlPort2 - NOT USED */
0, /* ulDataPort - NOT USED */
NULL, /* getRegister - NOT USED */
NULL, /* setRegister - NOT USED */
NULL, /* getData - NOT USED */
NULL, /* setData - NOT USED */
0, /* ulClock - NOT USED */
0 /* ulIntVector - NOT USED */
}};
console_tbl *BSP_get_uart_from_minor(int minor)
{
return Console_Port_Tbl[minor];
}

View File

@@ -56,8 +56,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
librtemsbsp_a_SOURCES += ../shared/arm-gic-irq.c
# Console
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
librtemsbsp_a_SOURCES += console/console-config.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/imx/console/console-config.c
# Clock
librtemsbsp_a_SOURCES += ../shared/arm-generic-timer-clock-config.c

View File

@@ -1,382 +0,0 @@
/*
* Copyright (c) 2017 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <info@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <sys/param.h>
#include <rtems/bspIo.h>
#include <rtems/console.h>
#include <rtems/sysinit.h>
#include <rtems/termiostypes.h>
#include <bsp.h>
#include <bsp/fdt.h>
#include <bsp/irq.h>
#include <arm/freescale/imx/imx_ccmvar.h>
#include <arm/freescale/imx/imx_uartreg.h>
#include <libfdt.h>
#define IMX_UART_TX_FIFO_LEVEL 16
typedef struct {
rtems_termios_device_context base;
volatile imx_uart *regs;
#ifdef CONSOLE_USE_INTERRUPTS
rtems_vector_number irq;
int tx_in_progress;
#endif
} imx_uart_context;
static imx_uart_context imx_uart_instances[7];
static imx_uart_context *imx_uart_console = &imx_uart_instances[0];
static volatile imx_uart *imx_uart_get_regs(rtems_termios_device_context *base)
{
imx_uart_context *ctx;
ctx = (imx_uart_context *) base;
return ctx->regs;
}
static void imx_uart_write_polled(rtems_termios_device_context *base, char c)
{
volatile imx_uart *regs;
regs = imx_uart_get_regs(base);
while ((regs->usr1 & IMX_UART_USR1_TRDY) == 0) {
/* Wait */
}
regs->utxd = IMX_UART_UTXD_TX_DATA(c);
}
void imx_uart_console_drain(void)
{
volatile imx_uart *regs;
regs = imx_uart_get_regs(&imx_uart_console->base);
if (regs != NULL) {
while ((regs->usr2 & IMX_UART_USR2_TXFE) == 0) {
/* Wait */
}
}
}
static void imx_output_char(char c)
{
imx_uart_write_polled(&imx_uart_console->base, c);
}
static void imx_uart_init_context(
imx_uart_context *ctx,
const char *fdt,
const char *serial
)
{
int node;
rtems_termios_device_context_initialize(&ctx->base, "UART");
node = fdt_path_offset(fdt, serial);
ctx->regs = imx_get_reg_of_node(fdt, node);
#ifdef CONSOLE_USE_INTERRUPTS
ctx->irq = imx_get_irq_of_node(fdt, node, 0);
#endif
}
static void imx_uart_probe(void)
{
const void *fdt;
int node;
int offset;
const char *console;
size_t i;
fdt = bsp_fdt_get();
node = fdt_path_offset(fdt, "/chosen");
console = fdt_getprop(fdt, node, "stdout-path", NULL);
if (console == NULL) {
console = "";
}
node = fdt_path_offset(fdt, "/aliases");
offset = fdt_first_property_offset(fdt, node);
i = 0;
while (offset >= 0 && i < RTEMS_ARRAY_SIZE(imx_uart_instances)) {
const struct fdt_property *prop;
prop = fdt_get_property_by_offset(fdt, offset, NULL);
if (prop != NULL) {
const char *name;
name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
if (strstr(name, "serial") != NULL) {
imx_uart_context *ctx;
const char *serial;
ctx = &imx_uart_instances[i];
serial = prop->data;
if (strcmp(serial, console) == 0) {
imx_uart_console = ctx;
}
imx_uart_init_context(ctx, fdt, serial);
++i;
}
}
offset = fdt_next_property_offset(fdt, offset);
}
BSP_output_char = imx_output_char;
}
static void imx_output_char_init(char c)
{
imx_uart_probe();
imx_output_char(c);
}
BSP_output_char_function_type BSP_output_char = imx_output_char_init;
BSP_polling_getchar_function_type BSP_poll_char = NULL;
#ifdef CONSOLE_USE_INTERRUPTS
static void imx_uart_interrupt(void *arg)
{
rtems_termios_tty *tty;
imx_uart_context *ctx;
volatile imx_uart *regs;
uint32_t usr2;
tty = arg;
ctx = rtems_termios_get_device_context(tty);
regs = ctx->regs;
usr2 = regs->usr2;
regs->usr1 = IMX_UART_USR1_AGTIM;
while ((usr2 & IMX_UART_USR2_RDR) != 0) {
char c;
c = IMX_UART_URXD_RX_DATA_GET(regs->urxd);
rtems_termios_enqueue_raw_characters(tty, &c, 1);
usr2 = regs->usr2;
}
if (ctx->tx_in_progress > 0 && (regs->usr1 & IMX_UART_USR1_TRDY) != 0) {
rtems_termios_dequeue_characters(tty, ctx->tx_in_progress);
}
}
#endif
static bool imx_uart_set_attributes(
rtems_termios_device_context *base,
const struct termios *term
)
{
imx_uart_context *ctx;
volatile imx_uart *regs;
uint32_t ufcr;
uint32_t baud;
ctx = (imx_uart_context *) base;
regs = imx_uart_get_regs(&ctx->base);
baud = rtems_termios_baud_to_number(term->c_ospeed);
if (baud != 0) {
ufcr = regs->ufcr;
ufcr = IMX_UART_UFCR_RFDIV_SET(ufcr, 0x5);
regs->ufcr = ufcr;
regs->ubir = 15;
regs->ubmr = imx_ccm_uart_hz() / baud - 1;
}
return true;
}
static bool imx_uart_first_open(
rtems_termios_tty *tty,
rtems_termios_device_context *base,
struct termios *term,
rtems_libio_open_close_args_t *args
)
{
imx_uart_context *ctx;
volatile imx_uart *regs;
#ifdef CONSOLE_USE_INTERRUPTS
rtems_status_code sc;
uint32_t ufcr;
#endif
ctx = (imx_uart_context *) base;
regs = imx_uart_get_regs(&ctx->base);
regs->ucr1 = IMX_UART_UCR1_UARTEN;
regs->ucr2 = IMX_UART_UCR2_IRTS | IMX_UART_UCR2_WS | IMX_UART_UCR2_RXEN
| IMX_UART_UCR2_TXEN | IMX_UART_UCR2_SRST;
rtems_termios_set_initial_baud(tty, 115200);
imx_uart_set_attributes(base, term);
#ifdef CONSOLE_USE_INTERRUPTS
ufcr = regs->ufcr;
ufcr = IMX_UART_UFCR_RXTL_SET(ufcr, 16);
ufcr = IMX_UART_UFCR_TXTL_SET(ufcr, IMX_UART_TX_FIFO_LEVEL);
regs->ufcr = ufcr;
regs->ucr1 |= IMX_UART_UCR1_RRDYEN;
regs->ucr2 |= IMX_UART_UCR2_ATEN;
sc = rtems_interrupt_handler_install(
ctx->irq,
"UART",
RTEMS_INTERRUPT_SHARED,
imx_uart_interrupt,
tty
);
if (sc != RTEMS_SUCCESSFUL) {
return false;
}
#endif
return true;
}
static void imx_uart_last_close(
rtems_termios_tty *tty,
rtems_termios_device_context *base,
rtems_libio_open_close_args_t *args
)
{
#ifdef CONSOLE_USE_INTERRUPTS
imx_uart_context *ctx;
ctx = (imx_uart_context *) base;
rtems_interrupt_handler_remove(ctx->irq, imx_uart_interrupt, tty);
#endif
}
static void imx_uart_write(
rtems_termios_device_context *base,
const char *buf,
size_t len
)
{
#ifdef CONSOLE_USE_INTERRUPTS
imx_uart_context *ctx;
volatile imx_uart *regs;
int n;
uint32_t ucr1;
ctx = (imx_uart_context *) base;
regs = imx_uart_get_regs(&ctx->base);
ucr1 = regs->ucr1;
if (len > 0) {
int i;
n = (int) MIN(len, IMX_UART_TX_FIFO_LEVEL);
ucr1 |= IMX_UART_UCR1_TRDYEN;
for (i = 0; i < n; ++i) {
regs->utxd = IMX_UART_UTXD_TX_DATA(buf[i]);
}
} else {
n = 0;
ucr1 &= ~IMX_UART_UCR1_TRDYEN;
}
regs->ucr1 = ucr1;
ctx->tx_in_progress = n;
#else
size_t i;
for (i = 0; i < len; ++i) {
imx_uart_write_polled(base, buf[i]);
}
#endif
}
#ifndef CONSOLE_USE_INTERRUPTS
static int imx_uart_read(rtems_termios_device_context *base)
{
volatile imx_uart *regs;
regs = imx_uart_get_regs(base);
if ((regs->usr2 & IMX_UART_USR2_RDR) != 0) {
return IMX_UART_URXD_RX_DATA_GET(regs->urxd);
} else {
return -1;
}
}
#endif
static const rtems_termios_device_handler imx_uart_handler = {
.first_open = imx_uart_first_open,
.last_close = imx_uart_last_close,
.write = imx_uart_write,
.set_attributes = imx_uart_set_attributes,
#ifdef CONSOLE_USE_INTERRUPTS
.mode = TERMIOS_IRQ_DRIVEN
#else
.poll_read = imx_uart_read,
.mode = TERMIOS_POLLED
#endif
};
rtems_status_code console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
char path[] = "/dev/ttyS?";
size_t i;
rtems_termios_initialize();
for (i = 0; i < RTEMS_ARRAY_SIZE(imx_uart_instances); ++i) {
imx_uart_context *ctx;
ctx = &imx_uart_instances[i];
path[sizeof(path) - 2] = (char) ('0' + i);
rtems_termios_device_install(
path,
&imx_uart_handler,
NULL,
&ctx->base
);
if (ctx == imx_uart_console) {
link(path, CONSOLE_DEVICE_NAME);
}
}
return RTEMS_SUCCESSFUL;
}
RTEMS_SYSINIT_ITEM(
imx_uart_probe,
RTEMS_SYSINIT_BSP_START,
RTEMS_SYSINIT_ORDER_LAST
);

View File

@@ -56,8 +56,8 @@ librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq-dispatch.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
librtemsbsp_a_SOURCES += console/console-config.c
librtemsbsp_a_SOURCES += console/uart.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lm3s69xx/console/console-config.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lm3s69xx/console/uart.c
# Clock
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-armv7m.c

View File

@@ -1,78 +0,0 @@
/*
* Copyright <20> 2013 Eugeniy Meshcheryakov <eugen@debian.org>
*
* Copyright (c) 2011 Sebastian Huber. All rights reserved.
*
* embedded brains GmbH
* Obere Lagerstr. 30
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems/bspIo.h>
#include <libchip/serial.h>
#include <bspopts.h>
#include <bsp/irq.h>
#include <bsp/uart.h>
#include <bsp/lm3s69xx.h>
console_tbl Console_Configuration_Ports [] = {
#ifdef LM3S69XX_ENABLE_UART_0
{
.sDeviceName = "/dev/ttyS0",
.deviceType = SERIAL_CUSTOM,
.pDeviceFns = &lm3s69xx_uart_fns,
.ulCtrlPort1 = LM3S69XX_UART_0_BASE,
.ulClock = LM3S69XX_UART_BAUD,
.ulIntVector = LM3S69XX_IRQ_UART_0,
.pDeviceParams = (void *)0
},
#endif
#ifdef LM3S69XX_ENABLE_UART_1
{
.sDeviceName = "/dev/ttyS1",
.deviceType = SERIAL_CUSTOM,
.pDeviceFns = &lm3s69xx_uart_fns,
.ulCtrlPort1 = LM3S69XX_UART_1_BASE,
.ulClock = LM3S69XX_UART_BAUD,
.ulIntVector = LM3S69XX_IRQ_UART_1,
.pDeviceParams = (void *)1
},
#endif
#ifdef LM3S69XX_ENABLE_UART_2
{
.sDeviceName = "/dev/ttyS2",
.deviceType = SERIAL_CUSTOM,
.pDeviceFns = &lm3s69xx_uart_fns,
.ulCtrlPort1 = LM3S69XX_UART_2_BASE,
.ulClock = LM3S69XX_UART_BAUD,
.ulIntVector = LM3S69XX_IRQ_UART_2,
.pDeviceParams = (void *)2
}
#endif
};
#define PORT_COUNT \
(sizeof(Console_Configuration_Ports) \
/ sizeof(Console_Configuration_Ports [0]))
unsigned long Console_Configuration_Count = PORT_COUNT;
static void output_char(char c)
{
const console_fns *con =
Console_Configuration_Ports [Console_Port_Minor].pDeviceFns;
con->deviceWritePolled((int) Console_Port_Minor, c);
}
BSP_output_char_function_type BSP_output_char = output_char;
BSP_polling_getchar_function_type BSP_poll_char = NULL;

View File

@@ -1,167 +0,0 @@
/*
* Copyright <20> 2013 Eugeniy Meshcheryakov <eugen@debian.org>
*
* Copyright (c) 2011 Sebastian Huber. All rights reserved.
*
* embedded brains GmbH
* Obere Lagerstr. 30
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bspopts.h>
#include <bsp/uart.h>
#include <libchip/sersupp.h>
#include <bsp/syscon.h>
#include <bsp/lm3s69xx.h>
#include <rtems/irq-extension.h>
#include <assert.h>
#define LM3S69XX_UART_FIFO_DEPTH 16
static volatile lm3s69xx_uart *get_uart_regs(int minor)
{
console_tbl *ct = Console_Port_Tbl [minor];
return (lm3s69xx_uart *) ct->ulCtrlPort1;
}
static unsigned int get_uart_number(int minor)
{
console_tbl *ct = Console_Port_Tbl [minor];
return (unsigned int)ct->pDeviceParams;
}
/*
* Returns both integer and fractional parts as one number.
*/
static uint32_t get_baud_div(uint32_t baud)
{
uint32_t clock4 = LM3S69XX_SYSTEM_CLOCK * 4;
return (clock4 + baud - 1) / baud;
}
static void irq_handler(void *arg)
{
int minor = (int)arg;
console_data *cd = &Console_Port_Data [minor];
volatile lm3s69xx_uart *uart = get_uart_regs(minor);
do {
char buf[LM3S69XX_UART_FIFO_DEPTH];
int i = 0;
uint32_t status = uart->fr;
while (((status & UARTFR_RXFE) == 0) && (i < LM3S69XX_UART_FIFO_DEPTH)) {
uint32_t d = uart->dr;
if ((d & UARTDR_ERROR_MSK) == 0) {
buf[i] = UARTDR_DATA_GET(d);
i++;
}
status = uart->fr;
}
if (i > 0)
rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i);
} while (uart->mis != 0);
}
static void initialize(int minor)
{
const console_tbl *ct = Console_Port_Tbl[minor];
volatile lm3s69xx_uart *uart = get_uart_regs(minor);
unsigned int num = get_uart_number(minor);
lm3s69xx_syscon_enable_uart_clock(num, true);
uart->ctl = 0;
uint32_t brd = get_baud_div(LM3S69XX_UART_BAUD);
uart->ibrd = brd / 64;
uart->fbrd = brd % 64;
uart->lcrh = UARTLCRH_WLEN(0x3) | UARTLCRH_FEN;
uart->ctl = UARTCTL_RXE | UARTCTL_TXE | UARTCTL_UARTEN;
int rv = rtems_interrupt_handler_install(ct->ulIntVector, "UART",
RTEMS_INTERRUPT_UNIQUE, irq_handler, (void *)minor);
assert(rv == RTEMS_SUCCESSFUL);
}
static int first_open(int major, int minor, void *arg)
{
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];
volatile lm3s69xx_uart *uart = get_uart_regs(minor);
cd->termios_data = tty;
rtems_termios_set_initial_baud(tty, LM3S69XX_UART_BAUD);
/* Drain the RX FIFO. */
while ((uart->fr & UARTFR_RXFE) == 0)
(void)uart->dr;
uart->im = UARTI_RX | UARTI_RT;
return 0;
}
static int last_close(int major, int minor, void *arg)
{
volatile lm3s69xx_uart *uart = get_uart_regs(minor);
uart->im = 0;
return 0;
}
static void write_polled(int minor, char c)
{
volatile lm3s69xx_uart *uart = get_uart_regs(minor);
while ((uart->fr & UARTFR_TXFF) != 0) {
/* Wait */
}
uart->dr = UARTDR_DATA(c);
}
static ssize_t write_support_polled(
int minor,
const char *s,
size_t n
)
{
ssize_t i = 0;
for (i = 0; i < n; ++i) {
write_polled(minor, s [i]);
}
return n;
}
static int set_attribues(int minor, const struct termios *term)
{
return -1;
}
const console_fns lm3s69xx_uart_fns = {
.deviceProbe = libchip_serial_default_probe,
.deviceFirstOpen = first_open,
.deviceLastClose = last_close,
.deviceRead = NULL,
.deviceWrite = write_support_polled,
.deviceInitialize = initialize,
.deviceWritePolled = write_polled,
.deviceSetAttributes = set_attribues,
.deviceOutputUsesInterrupts = false
};

View File

@@ -59,9 +59,9 @@ librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq-dispatch.c
librtemsbsp_a_SOURCES += irq/irq.c
# Console
librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
librtemsbsp_a_SOURCES += console/console-config.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc176x/console/console-config.c
# Clock
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-nxp-lpc.c

View File

@@ -1,192 +0,0 @@
/**
* @file
*
* @ingroup lpc176x
*
* @brief Console configuration.
*/
/*
* Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <libchip/ns16550.h>
#include <bsp.h>
#include <bsp/io.h>
#include <bsp/irq.h>
#include <bsp/console-termios.h>
/**
* @brief Gets the uart register according to the current address.
*
* @param addr Register address.
* @param i Index register.
* @return Uart register.
*/
static inline uint8_t lpc176x_uart_get_register(
const uintptr_t addr,
const uint8_t i
)
{
volatile uint32_t *reg = (volatile uint32_t *) addr;
return (uint8_t) reg[ i ];
}
/**
* @brief Sets the uart register address according to the value passed.
*
* @param addr Register address.
* @param i Index register.
* @param val Value to set.
*/
static inline void lpc176x_uart_set_register(
const uintptr_t addr,
const uint8_t i,
const uint8_t val
)
{
volatile uint32_t *reg = (volatile uint32_t *) addr;
reg[ i ] = val;
}
static bool lpc176x_uart1_probe(rtems_termios_device_context *ctx)
{
(void)ctx;
lpc176x_module_enable( LPC176X_MODULE_UART_1, LPC176X_MODULE_PCLK_DEFAULT );
lpc176x_pin_select( LPC176X_PIN_UART_1_TXD, LPC176X_PIN_FUNCTION_01 );
lpc176x_pin_select( LPC176X_PIN_UART_1_RXD, LPC176X_PIN_FUNCTION_01 );
return true;
}
#ifdef LPC176X_CONFIG_UART_2
static bool lpc176x_uart2_probe(rtems_termios_device_context *ctx)
{
(void)ctx;
lpc176x_module_enable( LPC176X_MODULE_UART_2, LPC176X_MODULE_PCLK_DEFAULT );
lpc176x_pin_select( LPC176X_PIN_UART_2_TXD, LPC176X_PIN_FUNCTION_01 );
lpc176x_pin_select( LPC176X_PIN_UART_2_RXD, LPC176X_PIN_FUNCTION_01 );
return true;
}
#endif
#ifdef LPC176X_CONFIG_UART_3
static bool lpc176x_uart3_probe(rtems_termios_device_context *ctx)
{
(void)ctx;
lpc176x_module_enable( LPC176X_MODULE_UART_3, LPC176X_MODULE_PCLK_DEFAULT );
lpc176x_pin_select( LPC176X_PIN_UART_3_TXD, LPC176X_PIN_FUNCTION_10 );
lpc176x_pin_select( LPC176X_PIN_UART_3_RXD, LPC176X_PIN_FUNCTION_10 );
return true;
}
#endif
#ifdef LPC176X_CONFIG_CONSOLE
static ns16550_context lpc176x_uart_context_0 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"),
.get_reg = lpc176x_uart_get_register,
.set_reg = lpc176x_uart_set_register,
.port = UART0_BASE_ADDR,
.irq = LPC176X_IRQ_UART_0,
.clock = LPC176X_PCLK,
.initial_baud = LPC176X_UART_BAUD,
.has_fractional_divider_register = true
};
#endif
#ifdef LPC176X_CONFIG_UART_1
static ns16550_context lpc176x_uart_context_1 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"),
.get_reg = lpc176x_uart_get_register,
.set_reg = lpc176x_uart_set_register,
.port = UART1_BASE_ADDR,
.irq = LPC176X_IRQ_UART_1,
.clock = LPC176X_PCLK,
.initial_baud = LPC176X_UART_BAUD,
.has_fractional_divider_register = true
};
#endif
#ifdef LPC176X_CONFIG_UART_2
static ns16550_context lpc176x_uart_context_2 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 2"),
.get_reg = lpc176x_uart_get_register,
.set_reg = lpc176x_uart_set_register,
.port = UART2_BASE_ADDR,
.irq = LPC176X_IRQ_UART_2,
.clock = LPC176X_PCLK,
.initial_baud = LPC176X_UART_BAUD,
.has_fractional_divider_register = true
};
#endif
#ifdef LPC176X_CONFIG_UART_3
static ns16550_context lpc176x_uart_context_3 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 3"),
.get_reg = lpc176x_uart_get_register,
.set_reg = lpc176x_uart_set_register,
.port = UART3_BASE_ADDR,
.irq = LPC176X_IRQ_UART_3,
.clock = LPC176X_PCLK,
.initial_baud = LPC176X_UART_BAUD,
.has_fractional_divider_register = true
};
#endif
const console_device console_device_table[] = {
#ifdef LPC176X_CONFIG_CONSOLE
{
.device_file = "/dev/ttyS0",
.probe = console_device_probe_default,
.handler = &ns16550_handler_interrupt,
.context = &lpc176x_uart_context_0.base
},
#endif
#ifdef LPC176X_CONFIG_UART_1
{
.device_file = "/dev/ttyS1",
.probe = lpc176x_uart1_probe,
.handler = &ns16550_handler_interrupt,
.context = &lpc176x_uart_context_1.base
},
#endif
#ifdef LPC176X_CONFIG_UART_2
{
.device_file = "/dev/ttyS2",
.probe = lpc176x_uart2_probe,
.handler = &ns16550_handler_interrupt,
.context = &lpc176x_uart_context_2.base
},
#endif
#ifdef LPC176X_CONFIG_UART_3
{
.device_file = "/dev/ttyS3",
.probe = lpc176x_uart3_probe,
.handler = &ns16550_handler_interrupt,
.context = &lpc176x_uart_context_3.base
},
#endif
};
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);

View File

@@ -71,12 +71,12 @@ librtemsbsp_a_SOURCES += irq/irq.c
librtemsbsp_a_SOURCES += irq/irq-dispatch.c
# Console
librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
librtemsbsp_a_SOURCES += console/console-config.c
librtemsbsp_a_SOURCES += console/uart-probe-1.c
librtemsbsp_a_SOURCES += console/uart-probe-2.c
librtemsbsp_a_SOURCES += console/uart-probe-3.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/console/console-config.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/console/uart-probe-1.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/console/uart-probe-2.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/console/uart-probe-3.c
# Clock
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-nxp-lpc.c

View File

@@ -1,134 +0,0 @@
/**
* @file
*
* @ingroup lpc24xx
*
* @brief Console configuration.
*/
/*
* Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems/console.h>
#include <libchip/ns16550.h>
#include <bsp.h>
#include <bsp/lpc24xx.h>
#include <bsp/irq.h>
#include <bsp/io.h>
#include <bsp/console-termios.h>
static uint8_t lpc24xx_uart_get_register(uintptr_t addr, uint8_t i)
{
volatile uint32_t *reg = (volatile uint32_t *) addr;
return (uint8_t) reg [i];
}
static void lpc24xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
{
volatile uint32_t *reg = (volatile uint32_t *) addr;
reg [i] = val;
}
#ifdef LPC24XX_CONFIG_CONSOLE
static ns16550_context lpc24xx_uart_context_0 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"),
.get_reg = lpc24xx_uart_get_register,
.set_reg = lpc24xx_uart_set_register,
.port = UART0_BASE_ADDR,
.irq = LPC24XX_IRQ_UART_0,
.clock = LPC24XX_PCLK,
.initial_baud = LPC24XX_UART_BAUD,
.has_fractional_divider_register = true
};
#endif
#ifdef LPC24XX_CONFIG_UART_1
static ns16550_context lpc24xx_uart_context_1 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"),
.get_reg = lpc24xx_uart_get_register,
.set_reg = lpc24xx_uart_set_register,
.port = UART1_BASE_ADDR,
.irq = LPC24XX_IRQ_UART_1,
.clock = LPC24XX_PCLK,
.initial_baud = LPC24XX_UART_BAUD,
.has_fractional_divider_register = true
};
#endif
#ifdef LPC24XX_CONFIG_UART_2
static ns16550_context lpc24xx_uart_context_2 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 2"),
.get_reg = lpc24xx_uart_get_register,
.set_reg = lpc24xx_uart_set_register,
.port = UART2_BASE_ADDR,
.irq = LPC24XX_IRQ_UART_2,
.clock = LPC24XX_PCLK,
.initial_baud = LPC24XX_UART_BAUD,
.has_fractional_divider_register = true
};
#endif
#ifdef LPC24XX_CONFIG_UART_3
static ns16550_context lpc24xx_uart_context_3 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 3"),
.get_reg = lpc24xx_uart_get_register,
.set_reg = lpc24xx_uart_set_register,
.port = UART3_BASE_ADDR,
.irq = LPC24XX_IRQ_UART_3,
.clock = LPC24XX_PCLK,
.initial_baud = LPC24XX_UART_BAUD,
.has_fractional_divider_register = true
};
#endif
const console_device console_device_table[] = {
#ifdef LPC24XX_CONFIG_CONSOLE
{
.device_file = "/dev/ttyS0",
.probe = console_device_probe_default,
.handler = &ns16550_handler_interrupt,
.context = &lpc24xx_uart_context_0.base
},
#endif
#ifdef LPC24XX_CONFIG_UART_1
{
.device_file = "/dev/ttyS1",
.probe = lpc24xx_uart_probe_1,
.handler = &ns16550_handler_interrupt,
.context = &lpc24xx_uart_context_1.base
},
#endif
#ifdef LPC24XX_CONFIG_UART_2
{
.device_file = "/dev/ttyS2",
.probe = lpc24xx_uart_probe_2,
.handler = &ns16550_handler_interrupt,
.context = &lpc24xx_uart_context_2.base
},
#endif
#ifdef LPC24XX_CONFIG_UART_3
{
.device_file = "/dev/ttyS3",
.probe = lpc24xx_uart_probe_3,
.handler = &ns16550_handler_interrupt,
.context = &lpc24xx_uart_context_3.base
},
#endif
};
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);

View File

@@ -1,40 +0,0 @@
/**
* @file
*
* @ingroup lpc24xx
*
* @brief UART 1 probe.
*/
/*
* Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <libchip/ns16550.h>
#include <bsp.h>
#include <bsp/io.h>
bool lpc24xx_uart_probe_1(rtems_termios_device_context *context)
{
static const lpc24xx_pin_range pins [] = {
LPC24XX_PIN_UART_1_TXD_P0_15,
LPC24XX_PIN_UART_1_RXD_P0_16,
LPC24XX_PIN_TERMINAL
};
lpc24xx_module_enable(LPC24XX_MODULE_UART_1, LPC24XX_MODULE_PCLK_DEFAULT);
lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION);
return ns16550_probe(context);
}

View File

@@ -1,40 +0,0 @@
/**
* @file
*
* @ingroup lpc24xx
*
* @brief UART 2 probe.
*/
/*
* Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <libchip/ns16550.h>
#include <bsp.h>
#include <bsp/io.h>
bool lpc24xx_uart_probe_2(rtems_termios_device_context *context)
{
static const lpc24xx_pin_range pins [] = {
LPC24XX_PIN_UART_2_TXD_P0_10,
LPC24XX_PIN_UART_2_RXD_P0_11,
LPC24XX_PIN_TERMINAL
};
lpc24xx_module_enable(LPC24XX_MODULE_UART_2, LPC24XX_MODULE_PCLK_DEFAULT);
lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION);
return ns16550_probe(context);
}

View File

@@ -1,40 +0,0 @@
/**
* @file
*
* @ingroup lpc24xx
*
* @brief UART 3 probe.
*/
/*
* Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <libchip/ns16550.h>
#include <bsp.h>
#include <bsp/io.h>
bool lpc24xx_uart_probe_3(rtems_termios_device_context *context)
{
static const lpc24xx_pin_range pins [] = {
LPC24XX_PIN_UART_3_TXD_P0_0,
LPC24XX_PIN_UART_3_RXD_P0_1,
LPC24XX_PIN_TERMINAL
};
lpc24xx_module_enable(LPC24XX_MODULE_UART_3, LPC24XX_MODULE_PCLK_DEFAULT);
lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION);
return ns16550_probe(context);
}

View File

@@ -59,10 +59,10 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
librtemsbsp_a_SOURCES += irq/irq.c
# Console
librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
librtemsbsp_a_SOURCES += console/console-config.c
librtemsbsp_a_SOURCES += console/hsu.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc32xx/console/console-config.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc32xx/console/hsu.c
# Clock
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-nxp-lpc.c

View File

@@ -1,225 +0,0 @@
/**
* @file
*
* @ingroup arm_lpc32xx
*
* @brief Console configuration.
*/
/*
* Copyright (c) 2009-2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <libchip/ns16550.h>
#include <bsp.h>
#include <bsp/lpc32xx.h>
#include <bsp/irq.h>
#include <bsp/hsu.h>
#include <bsp/console-termios.h>
static uint8_t lpc32xx_uart_get_register(uintptr_t addr, uint8_t i)
{
volatile uint32_t *reg = (volatile uint32_t *) addr;
return (uint8_t) reg [i];
}
static void lpc32xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
{
volatile uint32_t *reg = (volatile uint32_t *) addr;
reg [i] = val;
}
#ifdef LPC32XX_UART_3_BAUD
static bool lpc32xx_uart_probe_3(rtems_termios_device_context *context)
{
LPC32XX_UARTCLK_CTRL |= BSP_BIT32(0);
LPC32XX_U3CLK = LPC32XX_CONFIG_U3CLK;
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 4, 5);
return ns16550_probe(context);
}
#endif
#ifdef LPC32XX_UART_4_BAUD
static bool lpc32xx_uart_probe_4(rtems_termios_device_context *context)
{
volatile lpc32xx_gpio *gpio = &lpc32xx.gpio;
/*
* Set GPO_21/U4_TX/LCDVD[3] to U4_TX. This works only if LCD module is
* disabled.
*/
gpio->p2_mux_set = BSP_BIT32(2);
LPC32XX_UARTCLK_CTRL |= BSP_BIT32(1);
LPC32XX_U4CLK = LPC32XX_CONFIG_U4CLK;
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 6, 7);
return ns16550_probe(context);
}
#endif
#ifdef LPC32XX_UART_6_BAUD
static bool lpc32xx_uart_probe_6(rtems_termios_device_context *context)
{
/* Bypass the IrDA modulator/demodulator */
LPC32XX_UART_CTRL |= BSP_BIT32(5);
LPC32XX_UARTCLK_CTRL |= BSP_BIT32(3);
LPC32XX_U6CLK = LPC32XX_CONFIG_U6CLK;
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 10, 11);
return ns16550_probe(context);
}
#endif
/* FIXME: Console selection */
#ifdef LPC32XX_UART_5_BAUD
static ns16550_context lpc32xx_uart_context_5 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 5"),
.get_reg = lpc32xx_uart_get_register,
.set_reg = lpc32xx_uart_set_register,
.port = LPC32XX_BASE_UART_5,
.irq = LPC32XX_IRQ_UART_5,
.clock = 16 * LPC32XX_UART_5_BAUD,
.initial_baud = LPC32XX_UART_5_BAUD
};
#endif
#ifdef LPC32XX_UART_3_BAUD
static ns16550_context lpc32xx_uart_context_3 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 3"),
.get_reg = lpc32xx_uart_get_register,
.set_reg = lpc32xx_uart_set_register,
.port = LPC32XX_BASE_UART_3,
.irq = LPC32XX_IRQ_UART_3,
.clock = 16 * LPC32XX_UART_3_BAUD,
.initial_baud = LPC32XX_UART_3_BAUD
};
#endif
#ifdef LPC32XX_UART_4_BAUD
static ns16550_context lpc32xx_uart_context_4 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 4"),
.get_reg = lpc32xx_uart_get_register,
.set_reg = lpc32xx_uart_set_register,
.port = LPC32XX_BASE_UART_4,
.irq = LPC32XX_IRQ_UART_4,
.clock = 16 * LPC32XX_UART_4_BAUD,
.initial_baud = LPC32XX_UART_4_BAUD
};
#endif
#ifdef LPC32XX_UART_6_BAUD
static ns16550_context lpc32xx_uart_context_6 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 6"),
.get_reg = lpc32xx_uart_get_register,
.set_reg = lpc32xx_uart_set_register,
.port = LPC32XX_BASE_UART_6,
.irq = LPC32XX_IRQ_UART_6,
.clock = 16 * LPC32XX_UART_6_BAUD,
.initial_baud = LPC32XX_UART_6_BAUD
};
#endif
#ifdef LPC32XX_UART_1_BAUD
static lpc32xx_hsu_context lpc32xx_uart_context_1 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"),
.hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_1,
.irq = LPC32XX_IRQ_UART_1,
.initial_baud = LPC32XX_UART_1_BAUD
};
#endif
#ifdef LPC32XX_UART_2_BAUD
static lpc32xx_hsu_context lpc32xx_uart_context_2 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 2"),
.hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_2,
.irq = LPC32XX_IRQ_UART_2,
.initial_baud = LPC32XX_UART_2_BAUD
};
#endif
#ifdef LPC32XX_UART_7_BAUD
static lpc32xx_hsu_context lpc32xx_uart_context_7 = {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 7"),
.hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_7,
.irq = LPC32XX_IRQ_UART_7,
.initial_baud = LPC32XX_UART_7_BAUD
};
#endif
const console_device console_device_table[] = {
#ifdef LPC32XX_UART_5_BAUD
{
.device_file = "/dev/ttyS5",
.probe = console_device_probe_default,
.handler = &ns16550_handler_interrupt,
.context = &lpc32xx_uart_context_5.base
},
#endif
#ifdef LPC32XX_UART_3_BAUD
{
.device_file = "/dev/ttyS3",
.probe = lpc32xx_uart_probe_3,
.handler = &ns16550_handler_interrupt,
.context = &lpc32xx_uart_context_3.base
},
#endif
#ifdef LPC32XX_UART_4_BAUD
{
.device_file = "/dev/ttyS4",
.probe = lpc32xx_uart_probe_4,
.handler = &ns16550_handler_interrupt,
.context = &lpc32xx_uart_context_4.base
},
#endif
#ifdef LPC32XX_UART_6_BAUD
{
.device_file = "/dev/ttyS6",
.probe = lpc32xx_uart_probe_6,
.handler = &ns16550_handler_interrupt,
.context = &lpc32xx_uart_context_6.base
},
#endif
#ifdef LPC32XX_UART_1_BAUD
{
.device_file = "/dev/ttyS1",
.probe = lpc32xx_hsu_probe,
.handler = &lpc32xx_hsu_fns,
.context = &lpc32xx_uart_context_1.base
},
#endif
#ifdef LPC32XX_UART_2_BAUD
{
.device_file = "/dev/ttyS2",
.probe = lpc32xx_hsu_probe,
.handler = &lpc32xx_hsu_fns,
.context = &lpc32xx_uart_context_2.base
},
#endif
#ifdef LPC32XX_UART_7_BAUD
{
.device_file = "/dev/ttyS7",
.probe = lpc32xx_hsu_probe,
.handler = &lpc32xx_hsu_fns,
.context = &lpc32xx_uart_context_7.base
},
#endif
};
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);

View File

@@ -1,208 +0,0 @@
/**
* @file
*
* @ingroup arm_lpc32xx
*
* @brief High speed UART driver (14-clock).
*/
/*
* Copyright (c) 2010-2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <bsp/lpc32xx.h>
#include <bsp/irq.h>
#include <bsp/hsu.h>
#define HSU_FIFO_SIZE 64
#define HSU_LEVEL_RX_MASK 0xffU
#define HSU_LEVEL_TX_MASK 0xff00U
#define HSU_LEVEL_TX_SHIFT 8
#define HSU_RX_DATA_MASK 0xffU
#define HSU_RX_EMPTY (1U << 8)
#define HSU_RX_ERROR (1U << 9)
#define HSU_RX_BREAK (1U << 10)
#define HSU_IIR_TX (1U << 0)
#define HSU_IIR_RX_TRIG (1U << 1)
#define HSU_IIR_RX_TIMEOUT (1U << 2)
#define HSU_CTRL_INTR_DISABLED 0x1280fU
#define HSU_CTRL_RX_INTR_ENABLED 0x1284fU
#define HSU_CTRL_RX_AND_TX_INTR_ENABLED 0x1286fU
/* We are interested in RX timeout, RX trigger and TX trigger interrupts */
#define HSU_IIR_MASK 0x7U
bool lpc32xx_hsu_probe(rtems_termios_device_context *base)
{
lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
volatile lpc32xx_hsu *hsu = ctx->hsu;
hsu->ctrl = HSU_CTRL_INTR_DISABLED;
/* Drain FIFOs */
while (hsu->level != 0) {
hsu->fifo;
}
return true;
}
static void lpc32xx_hsu_interrupt_handler(void *arg)
{
rtems_termios_tty *tty = arg;
lpc32xx_hsu_context *ctx = rtems_termios_get_device_context(tty);
volatile lpc32xx_hsu *hsu = ctx->hsu;
/* Iterate until no more interrupts are pending */
do {
int rv = 0;
int i = 0;
char buf [HSU_FIFO_SIZE];
/* Enqueue received characters */
while (i < HSU_FIFO_SIZE) {
uint32_t in = hsu->fifo;
if ((in & HSU_RX_EMPTY) == 0) {
if ((in & HSU_RX_BREAK) == 0) {
buf [i] = in & HSU_RX_DATA_MASK;
++i;
}
} else {
break;
}
}
rtems_termios_enqueue_raw_characters(tty, buf, i);
/* Dequeue transmitted characters */
rv = rtems_termios_dequeue_characters(tty, (int) ctx->chars_in_transmission);
if (rv == 0) {
/* Nothing to transmit */
}
} while ((hsu->iir & HSU_IIR_MASK) != 0);
}
static bool lpc32xx_hsu_first_open(
struct rtems_termios_tty *tty,
rtems_termios_device_context *base,
struct termios *term,
rtems_libio_open_close_args_t *args
)
{
lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
volatile lpc32xx_hsu *hsu = ctx->hsu;
rtems_status_code sc;
bool ok;
sc = rtems_interrupt_handler_install(
ctx->irq,
"HSU",
RTEMS_INTERRUPT_UNIQUE,
lpc32xx_hsu_interrupt_handler,
tty
);
ok = sc == RTEMS_SUCCESSFUL;
if (ok) {
rtems_termios_set_initial_baud(tty, ctx->initial_baud);
hsu->ctrl = HSU_CTRL_RX_INTR_ENABLED;
}
return ok;
}
static void lpc32xx_hsu_last_close(
struct rtems_termios_tty *tty,
rtems_termios_device_context *base,
rtems_libio_open_close_args_t *args
)
{
lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
volatile lpc32xx_hsu *hsu = ctx->hsu;
hsu->ctrl = HSU_CTRL_INTR_DISABLED;
rtems_interrupt_handler_remove(
ctx->irq,
lpc32xx_hsu_interrupt_handler,
tty
);
}
static void lpc32xx_hsu_write(
rtems_termios_device_context *base,
const char *buf,
size_t len
)
{
lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
volatile lpc32xx_hsu *hsu = ctx->hsu;
size_t tx_level = (hsu->level & HSU_LEVEL_TX_MASK) >> HSU_LEVEL_TX_SHIFT;
size_t tx_free = HSU_FIFO_SIZE - tx_level;
size_t i = 0;
size_t out = len > tx_free ? tx_free : len;
for (i = 0; i < out; ++i) {
hsu->fifo = buf [i];
}
ctx->chars_in_transmission = out;
if (len > 0) {
hsu->ctrl = HSU_CTRL_RX_AND_TX_INTR_ENABLED;
} else {
hsu->ctrl = HSU_CTRL_RX_INTR_ENABLED;
hsu->iir = HSU_IIR_TX;
}
}
static bool lpc32xx_hsu_set_attributes(
rtems_termios_device_context *base,
const struct termios *term
)
{
lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
volatile lpc32xx_hsu *hsu = ctx->hsu;
int baud_flags = term->c_ospeed;
if (baud_flags != 0) {
int32_t baud = rtems_termios_baud_to_number(baud_flags);
if (baud > 0) {
uint32_t baud_divisor = 14 * (uint32_t) baud;
uint32_t rate = LPC32XX_PERIPH_CLK / baud_divisor;
uint32_t remainder = LPC32XX_PERIPH_CLK - rate * baud_divisor;
if (2 * remainder >= baud_divisor) {
++rate;
}
hsu->rate = rate - 1;
}
}
return true;
}
const rtems_termios_device_handler lpc32xx_hsu_fns = {
.first_open = lpc32xx_hsu_first_open,
.last_close = lpc32xx_hsu_last_close,
.write = lpc32xx_hsu_write,
.set_attributes = lpc32xx_hsu_set_attributes,
.mode = TERMIOS_IRQ_DRIVEN
};

View File

@@ -16,7 +16,7 @@ dist_project_lib_DATA = startup/bsp_specs
# Header #
###############################################################################
noinst_HEADERS = console/font_data.h
noinst_HEADERS = ../../../../../../bsps/arm/raspberrypi/console/font_data.h
###############################################################################
# Data #
@@ -68,12 +68,12 @@ librtemsbsp_a_SOURCES += irq/irq.c
# Console
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
librtemsbsp_a_SOURCES += console/console-config.c
librtemsbsp_a_SOURCES += console/console_select.c
librtemsbsp_a_SOURCES += console/usart.c
librtemsbsp_a_SOURCES += console/fb.c
librtemsbsp_a_SOURCES += console/fbcons.c
librtemsbsp_a_SOURCES += console/outch.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/console-config.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/console_select.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/usart.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/fb.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/fbcons.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/outch.c
# Mailbox
librtemsbsp_a_SOURCES += misc/mailbox.c

View File

@@ -1,68 +0,0 @@
/**
* @file
*
* @ingroup raspberrypi_usart
*
* @brief Console Configuration.
*/
/*
* Copyright (c) 2015 Yang Qiao
* based on work by:
* Copyright (c) 2013 Alan Cudmore
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
* http://www.rtems.org/license/LICENSE
*
*/
#include <rtems/bspIo.h>
#include <libchip/serial.h>
#include <bspopts.h>
#include <bsp/irq.h>
#include <bsp/usart.h>
#include <bsp/raspberrypi.h>
#include <bsp/fbcons.h>
console_tbl Console_Configuration_Ports [] = {
{
.sDeviceName = "/dev/ttyS0",
.deviceType = SERIAL_CUSTOM,
.pDeviceFns = &bcm2835_usart_fns,
.deviceProbe = NULL,
.pDeviceFlow = NULL,
.ulCtrlPort1 = BCM2835_UART0_BASE,
.ulCtrlPort2 = 0,
.ulClock = USART0_DEFAULT_BAUD,
.ulIntVector = BCM2835_IRQ_ID_UART
},
{
.sDeviceName ="/dev/fbcons",
.deviceType = SERIAL_CUSTOM,
.pDeviceFns = &fbcons_fns,
.deviceProbe = fbcons_probe,
.pDeviceFlow = NULL,
},
};
#define PORT_COUNT \
(sizeof(Console_Configuration_Ports) \
/ sizeof(Console_Configuration_Ports [0]))
unsigned long Console_Configuration_Count = PORT_COUNT;
static void output_char(char c)
{
const console_fns *con =
Console_Configuration_Ports [Console_Port_Minor].pDeviceFns;
con->deviceWritePolled((int) Console_Port_Minor, c);
}
BSP_output_char_function_type BSP_output_char = output_char;
BSP_polling_getchar_function_type BSP_poll_char = NULL;

View File

@@ -1,114 +0,0 @@
/**
* @file
*
* @ingroup raspberrypi_console
*
* @brief console select
*/
/*
* Copyright (c) 2015 Yang Qiao
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
* http://www.rtems.org/license/LICENSE
*
*/
#include <bsp.h>
#include <bsp/fatal.h>
#include <rtems/libio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <termios.h>
#include <rtems/termiostypes.h>
#include <libchip/serial.h>
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
#include <bsp/rpi-fb.h>
rtems_device_minor_number BSPPrintkPort = 0;
/*
* Method to return true if the device associated with the
* minor number probs available.
*/
static bool bsp_Is_Available( rtems_device_minor_number minor )
{
console_tbl *cptr = Console_Port_Tbl[ minor ];
/*
* First perform the configuration dependent probe, then the
* device dependent probe
*/
if ( ( !cptr->deviceProbe || cptr->deviceProbe( minor ) ) &&
cptr->pDeviceFns->deviceProbe( minor ) ) {
return true;
}
return false;
}
/*
* Method to return the first available device.
*/
static rtems_device_minor_number bsp_First_Available_Device( void )
{
rtems_device_minor_number minor;
for ( minor = 0; minor < Console_Port_Count; minor++ ) {
console_tbl *cptr = Console_Port_Tbl[ minor ];
/*
* First perform the configuration dependent probe, then the
* device dependent probe
*/
if ( ( !cptr->deviceProbe || cptr->deviceProbe( minor ) ) &&
cptr->pDeviceFns->deviceProbe( minor ) ) {
return minor;
}
}
/*
* Error No devices were found. We will want to bail here.
*/
bsp_fatal( BSP_FATAL_CONSOLE_NO_DEV );
}
void bsp_console_select( void )
{
/*
* Reset Console_Port_Minor and
* BSPPrintkPort here if desired.
*
* This default version allows the bsp to set these
* values at creation and will not touch them again
* unless the selected port number is not available.
*/
const char *opt;
Console_Port_Minor = BSP_CONSOLE_UART0;
BSPPrintkPort = BSP_CONSOLE_UART0;
opt = rpi_cmdline_get_arg( "--console=" );
if ( opt ) {
if ( strncmp( opt, "fbcons", sizeof( "fbcons" ) - 1 ) == 0 ) {
if ( rpi_video_is_initialized() > 0 ) {
Console_Port_Minor = BSP_CONSOLE_FB;
BSPPrintkPort = BSP_CONSOLE_FB;
}
}
}
/*
* If the device that was selected isn't available then
* let the user know and select the first available device.
*/
if ( !bsp_Is_Available( Console_Port_Minor ) ) {
Console_Port_Minor = bsp_First_Available_Device();
}
}

View File

@@ -1,437 +0,0 @@
/**
* @file
*
* @ingroup raspberrypi
*
* @brief framebuffer support.
*/
/*
* Copyright (c) 2015 Yang Qiao
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
* http://www.rtems.org/license/LICENSE
*
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <bsp.h>
#include <bsp/raspberrypi.h>
#include <bsp/mailbox.h>
#include <bsp/vc.h>
#include <bsp/rpi-fb.h>
#include <libcpu/arm-cp15.h>
#include <rtems.h>
#include <rtems/libio.h>
#include <rtems/fb.h>
#include <rtems/framebuffer.h>
#include <rtems/score/atomic.h>
#include <rtems/bspIo.h>
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 768
#define BPP 32
/* flag to limit driver to protect against multiple opens */
static Atomic_Flag driver_mutex;
/*
* screen information for the driver (fb0).
*/
static struct fb_var_screeninfo fb_var_info = {
.xres = SCREEN_WIDTH,
.yres = SCREEN_HEIGHT,
.bits_per_pixel = BPP
};
static struct fb_fix_screeninfo fb_fix_info = {
.smem_start = (void *) NULL,
.smem_len = 0,
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
.line_length = 0
};
typedef enum {
NO_SUITABLE_MODE = -1,
BAD_FORMAT = -2,
AUTO_SELECT = -3,
DONT_INIT = -4,
NO_MODE_REQ = -5,
} mode_err_ret_val;
int rpi_get_fix_screen_info( struct fb_fix_screeninfo *info )
{
*info = fb_fix_info;
return 0;
}
int rpi_get_var_screen_info( struct fb_var_screeninfo *info )
{
*info = fb_var_info;
return 0;
}
/**
* @brief Find mode given in string format.
*
* expected format
* <resX>x<resY>[-<bpp>]
* numbers <resX>, <resY> and <bpp> are decadic
*
* @param[out] fb_var_ptr pointer to variable mode part filled by function
* @param[in] video_string string to be parsed
* @retval video mode number to be set
* @retval -1 no suitable mode found
* @retval -2 bad format of the video_string
* @retval -3 automatic mode selection requested
* @retval -4 request to not initialize graphics
* @retval -5 no mode requested/empty video string
*/
static int parse_mode_from_string(
struct fb_var_screeninfo *fb_var_ptr,
const char *video_string
)
{
const char *opt;
char *endptr;
uint32_t width;
uint32_t height;
uint32_t bpp = 0;
opt = video_string;
if ( opt == NULL )
return NO_MODE_REQ;
if ( strncmp( opt, "auto", 4 ) == 0 )
return AUTO_SELECT;
if ( strncmp( opt, "none", 4 ) == 0 ||
strncmp( opt, "off", 3 ) == 0 )
return DONT_INIT;
width = strtol( opt, &endptr, 10 );
if ( *endptr != 'x' ) {
return BAD_FORMAT;
}
opt = endptr + 1;
height = strtol( opt, &endptr, 10 );
switch ( *endptr ) {
case '-':
opt = endptr + 1;
endptr = NULL;
bpp = strtol( opt, &endptr, 10 );
if ( ( endptr == opt ) || ( endptr == NULL ) )
return BAD_FORMAT;
if ( *endptr && ( *endptr != ' ' ) )
return BAD_FORMAT;
break;
case ' ':
case 0:
break;
default:
return BAD_FORMAT;
}
fb_var_ptr->xres = width;
fb_var_ptr->yres = height;
if ( bpp != 0 )
fb_var_ptr->bits_per_pixel = bpp;
return 0;
}
static int find_mode_from_vc( void )
{
int res;
unsigned int width;
unsigned int height;
bcm2835_get_display_size_entries entries;
res = bcm2835_mailbox_get_display_size( &entries );
width = entries.width;
height = entries.height;
if ( width == 0 || height == 0 ) {
fb_var_info.xres = SCREEN_WIDTH;
fb_var_info.yres = SCREEN_HEIGHT;
} else {
fb_var_info.xres = width;
fb_var_info.yres = height;
}
printk("find_mode_from_vc %u x %u, res %d\n", width, height, res);
return res;
}
bool rpi_fb_hdmi_is_present( void )
{
bcm2835_get_display_size_entries entries;
memset( &entries, 0, sizeof( entries ) );
bcm2835_mailbox_get_display_size( &entries );
/* Impossible display dimension */
if ( ( entries.width < 10 ) || ( entries.height < 10 ) )
return false;
/* Know default values reported when monitor is not present */
if ( ( entries.width == 0x290 ) && ( entries.height == 0x1A0 ) )
return false;
return true;
}
int rpi_fb_init( void )
{
int res;
int mode_from_cmdline;
bcm2835_init_frame_buffer_entries init_frame_buffer_entries;
if ( fb_fix_info.smem_start != NULL ) {
return RPI_FB_INIT_ALREADY_INITIALIZED;
}
if ( rpi_fb_hdmi_is_present() == false ) {
return RPI_FB_INIT_NO_DISPLAY;
}
mode_from_cmdline = parse_mode_from_string( &fb_var_info,
rpi_cmdline_get_arg( "--video=" ) );
switch ( mode_from_cmdline ) {
case BAD_FORMAT:
return RPI_FB_INIT_CMDLINE_BAD_FORMAT;
case AUTO_SELECT:
break;
case DONT_INIT:
return RPI_FB_INIT_CMDLINE_DONT_INIT;
case NO_MODE_REQ:
return RPI_FB_INIT_CMDLINE_NO_MODE_REQ;
}
if ( mode_from_cmdline ) {
if ( find_mode_from_vc() )
return RPI_FB_INIT_MODE_PROBE_ERROR;
}
memset( &init_frame_buffer_entries, 0, sizeof( init_frame_buffer_entries ) );
init_frame_buffer_entries.xres = fb_var_info.xres;
init_frame_buffer_entries.yres = fb_var_info.yres;
init_frame_buffer_entries.xvirt = fb_var_info.xres;
init_frame_buffer_entries.yvirt = fb_var_info.yres;
init_frame_buffer_entries.depth = fb_var_info.bits_per_pixel;
init_frame_buffer_entries.pixel_order = bcm2835_mailbox_pixel_order_rgb;
init_frame_buffer_entries.alpha_mode = bcm2835_mailbox_alpha_mode_0_opaque;
init_frame_buffer_entries.voffset_x = 0;
init_frame_buffer_entries.voffset_y = 0;
init_frame_buffer_entries.overscan_left = 0;
init_frame_buffer_entries.overscan_right = 0;
init_frame_buffer_entries.overscan_top = 0;
init_frame_buffer_entries.overscan_bottom = 0;
printk("bcm2835_mailbox_init_frame_buffer ...\n");
res = bcm2835_mailbox_init_frame_buffer( &init_frame_buffer_entries );
printk("bcm2835_mailbox_init_frame_buffer returned %d\n", res);
if (res != 0) {
printk("bcm2835_mailbox_init_frame_buffer retry ...\n");
res = bcm2835_mailbox_init_frame_buffer( &init_frame_buffer_entries );
printk("bcm2835_mailbox_init_frame_buffer returned %d\n", res);
if (res != 0)
return RPI_FB_INIT_SETUP_FAILED;
}
bcm2835_get_pitch_entries get_pitch_entries;
bcm2835_mailbox_get_pitch( &get_pitch_entries );
fb_var_info.xres = init_frame_buffer_entries.xres;
fb_var_info.yres = init_frame_buffer_entries.yres;
fb_var_info.bits_per_pixel = init_frame_buffer_entries.depth;
fb_fix_info.smem_start = (void *) init_frame_buffer_entries.base;
fb_fix_info.smem_len = init_frame_buffer_entries.size;
fb_fix_info.line_length = get_pitch_entries.pitch;
if ( fb_fix_info.smem_start == NULL )
return RPI_FB_INIT_START_ADDR_UNKNOWN;
printk("fb_fix_info.smem_start %p\n", fb_fix_info.smem_start);
arm_cp15_set_translation_table_entries( (void *) fb_fix_info.smem_start,
(void *) fb_fix_info.smem_start +
fb_fix_info.smem_len,
ARMV7_MMU_DATA_READ_WRITE_CACHED );
return RPI_FB_INIT_OK;
}
/*
* fbds device driver initialize entry point.
*/
rtems_device_driver frame_buffer_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code status;
/* register the devices */
status = rtems_io_register_name( FRAMEBUFFER_DEVICE_0_NAME, major, 0 );
if ( status != RTEMS_SUCCESSFUL ) {
printk( "[!] error registering framebuffer\n" );
rtems_fatal_error_occurred( status );
}
_Atomic_Flag_clear( &driver_mutex, ATOMIC_ORDER_RELEASE );
return RTEMS_SUCCESSFUL;
}
/*
* fbds device driver open operation.
*/
rtems_device_driver frame_buffer_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
if ( _Atomic_Flag_test_and_set( &driver_mutex,
ATOMIC_ORDER_ACQUIRE ) != 0 ) {
printk( "RaspberryPi framebuffer could not lock driver_mutex\n" );
return RTEMS_UNSATISFIED;
}
if ( fb_fix_info.smem_start == NULL ) {
int res;
res = rpi_fb_init();
if ( (res < RPI_FB_INIT_OK) || (fb_fix_info.smem_start == NULL) ) {
_Atomic_Flag_clear( &driver_mutex, ATOMIC_ORDER_RELEASE );
printk( "RaspberryPi framebuffer initialization failed\n" );
return RTEMS_UNSATISFIED;
}
}
memset( (void *) fb_fix_info.smem_start, 0, fb_fix_info.smem_len );
return RTEMS_SUCCESSFUL;
}
/*
* fbds device driver close operation.
*/
rtems_device_driver frame_buffer_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
/* restore previous state. for VGA this means return to text mode.
* leave out if graphics hardware has been initialized in
* frame_buffer_initialize() */
memset( (void *) fb_fix_info.smem_start, 0, fb_fix_info.smem_len );
_Atomic_Flag_clear( &driver_mutex, ATOMIC_ORDER_RELEASE );
return RTEMS_SUCCESSFUL;
}
/*
* fbds device driver read operation.
*/
rtems_device_driver frame_buffer_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
rw_args->bytes_moved =
( ( rw_args->offset + rw_args->count ) > fb_fix_info.smem_len ) ?
( fb_fix_info.smem_len - rw_args->offset ) : rw_args->count;
memcpy( rw_args->buffer,
(const void *) ( fb_fix_info.smem_start + rw_args->offset ),
rw_args->bytes_moved );
return RTEMS_SUCCESSFUL;
}
/*
* fbds device driver write operation.
*/
rtems_device_driver frame_buffer_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
rw_args->bytes_moved =
( ( rw_args->offset + rw_args->count ) > fb_fix_info.smem_len ) ?
( fb_fix_info.smem_len - rw_args->offset ) : rw_args->count;
memcpy( (void *) ( fb_fix_info.smem_start + rw_args->offset ),
rw_args->buffer,
rw_args->bytes_moved );
return RTEMS_SUCCESSFUL;
}
/*
* ioctl entry point.
*/
rtems_device_driver frame_buffer_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_ioctl_args_t *args = arg;
/* XXX check minor */
switch ( args->command ) {
case FBIOGET_VSCREENINFO:
memcpy( args->buffer, &fb_var_info, sizeof( fb_var_info ) );
args->ioctl_return = 0;
break;
case FBIOGET_FSCREENINFO:
memcpy( args->buffer, &fb_fix_info, sizeof( fb_fix_info ) );
args->ioctl_return = 0;
break;
case FBIOGETCMAP:
/* no palette - truecolor mode */
args->ioctl_return = -1;
return RTEMS_UNSATISFIED;
case FBIOPUTCMAP:
/* no palette - truecolor mode */
args->ioctl_return = -1;
return RTEMS_UNSATISFIED;
default:
args->ioctl_return = -1;
return RTEMS_UNSATISFIED;
}
return RTEMS_SUCCESSFUL;
}

View File

@@ -1,177 +0,0 @@
/**
* @file
*
* @ingroup raspberrypi_console
*
* @brief framebuffer graphic console support.
*/
/*
* Copyright (c) 2015 Yang Qiao
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
* http://www.rtems.org/license/LICENSE
*
*/
#include <rtems.h>
#include <rtems/libio.h>
#include <stdlib.h>
#include <libchip/serial.h>
#include <libchip/sersupp.h>
#include <bsp.h>
#include <bsp/fbcons.h>
#include <bsp/vc.h>
#include <bsp/rpi-fb.h>
/*
* fbcons_init
*
* This function initializes the fb console to a quiecsent state.
*/
static void fbcons_init( int minor )
{
}
/*
* fbcons_open
*
* This function opens a port for communication.
*
* Default state is 9600 baud, 8 bits, No parity, and 1 stop bit.
*/
static int fbcons_open(
int major,
int minor,
void *arg
)
{
return RTEMS_SUCCESSFUL;
}
/*
* fbcons_close
*
* This function shuts down the requested port.
*/
static int fbcons_close(
int major,
int minor,
void *arg
)
{
return ( RTEMS_SUCCESSFUL );
}
/*
* fbcons_write_polled
*
* This routine polls out the requested character.
*/
static void fbcons_write_polled(
int minor,
char c
)
{
rpi_fb_outch( c );
if ( c == '\n' )
rpi_fb_outch( '\r' ); /* LF = LF + CR */
}
/*
* fbcons_write_support_polled
*
* Console Termios output entry point when using polled output.
*
*/
static ssize_t fbcons_write_support_polled(
int minor,
const char *buf,
size_t len
)
{
int nwrite = 0;
/*
* poll each byte in the string out of the port.
*/
while ( nwrite < len ) {
fbcons_write_polled( minor, *buf++ );
nwrite++;
}
/*
* return the number of bytes written.
*/
return nwrite;
}
/*
* fbcons_inbyte_nonblocking_polled
*
* Console Termios polling input entry point.
*/
static int fbcons_inbyte_nonblocking_polled( int minor )
{
// if( rtems_kbpoll() ) {
// int c = getch();
// return c;
// }
return -1;
}
/*
* fbcons_set_attributes
*
* This function sets the UART channel to reflect the requested termios
* port settings.
*/
static int fbcons_set_attributes(
int minor,
const struct termios *t
)
{
return 0;
}
bool fbcons_probe( int minor )
{
// rtems_status_code status;
static bool firstTime = true;
static bool ret = false;
/*
* keyboard interrupt should be registered when the keyboard is available
*/
if ( firstTime ) {
if ( !rpi_fb_hdmi_is_present() ) {
ret = false;
} else {
ret = true;
}
}
firstTime = false;
return ret;
}
const console_fns fbcons_fns =
{
.deviceProbe = libchip_serial_default_probe, /* deviceProbe */
.deviceFirstOpen = fbcons_open, /* deviceFirstOpen */
.deviceLastClose = fbcons_close, /* deviceLastClose */
.deviceRead = fbcons_inbyte_nonblocking_polled, /* deviceRead */
.deviceWrite = fbcons_write_support_polled, /* deviceWrite */
.deviceInitialize = fbcons_init, /* deviceInitialize */
.deviceWritePolled = fbcons_write_polled, /* deviceWritePolled */
.deviceSetAttributes = fbcons_set_attributes, /* deviceSetAttributes */
.deviceOutputUsesInterrupts = FALSE, /* deviceOutputUsesInterrupts*/
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,463 +0,0 @@
/**
* @file
*
* @ingroup raspberrypi
*
* @brief displaying characters on the console
*/
/**
*
* Copyright (c) 2015 Yang Qiao
* based on work by:
* Copyright (C) 1998 Eric Valette (valette@crf.canon.fr)
* Canon Centre Recherche France.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Till Straumann <strauman@slac.stanford.edu>, 2003/9:
* - added handling of basic escape sequences (cursor movement
* and erasing; just enough for the line editor 'libtecla' to
* work...)
*
*/
#include <bsp.h>
#include <bsp/vc.h>
#include <bsp/rpi-fb.h>
#include <rtems/fb.h>
#include <stdlib.h>
#include <string.h>
#include "font_data.h"
static void wr_cursor(
int r,
int c
)
{
/* dummy function for now */
}
#define TAB_SPACE 4
#define CONSOLE_BG_COL 0x00
#define CONSOLE_FG_COL 0xa0
static void *fb_mem = NULL;
static unsigned short maxCol;
static unsigned short maxRow;
static unsigned short bytes_per_pixel;
static unsigned int bytes_per_line;
static unsigned int bytes_per_char_line;
static unsigned char row;
static unsigned char column;
static unsigned int nLines;
static uint32_t fgx, bgx, eorx;
static int rpi_video_initialized;
static const int video_font_draw_table32[ 16 ][ 4 ] = {
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x00000000, 0x00000000, 0x00000000, 0x00ffffff },
{ 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 },
{ 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff },
{ 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 },
{ 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
{ 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 },
{ 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff },
{ 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 },
{ 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff },
{ 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 },
{ 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff },
{ 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 },
{ 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff },
{ 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 },
{ 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff }
};
static void scroll( void )
{
int i, j; /* Counters */
uint8_t *pt_scroll, *pt_bitmap; /* Pointers on the bit-map */
pt_bitmap = fb_mem;
j = 0;
pt_bitmap = pt_bitmap + j;
pt_scroll = pt_bitmap + bytes_per_char_line;
for ( i = j; i < maxRow - 1; i++ ) {
memcpy( pt_bitmap, pt_scroll, bytes_per_char_line );
pt_bitmap = pt_bitmap + bytes_per_char_line;
pt_scroll = pt_bitmap + bytes_per_char_line;
}
/*
* Blank characters are displayed on the last line.
*/
memset( pt_bitmap, 0, bytes_per_char_line );
}
static void doCRNL(
int cr,
int nl
)
{
if ( nl ) {
if ( ++row == maxRow ) {
scroll(); /* Scroll the screen now */
row = maxRow - 1;
}
nLines++;
}
if ( cr )
column = 0;
/* Move cursor on the next location */
if ( cr || nl ) {
wr_cursor( row, column );
}
}
static void advanceCursor( void )
{
if ( ++column == maxCol )
doCRNL( 1, 1 );
else
wr_cursor( row, column );
}
static void gotorc(
int r,
int c
)
{
column = c;
row = r;
wr_cursor( row, column );
}
static void video_drawchars(
int r,
int c,
unsigned char ch
)
{
if ( fb_mem == NULL ) {
return;
}
uint8_t *cdat, *dest, *dest0;
int rows, offset;
offset = r * bytes_per_char_line + c * bytes_per_pixel * RPI_FONT_WIDTH;
dest0 = fb_mem + offset;
/*
* only 32-bit per pixel format is supported for now
*/
cdat = rpi_font + ch * RPI_FONT_HEIGHT;
for ( rows = RPI_FONT_HEIGHT, dest = dest0;
rows--; dest += bytes_per_line ) {
uint8_t bits = *cdat++;
( (uint32_t *) dest )[ 0 ] =
( video_font_draw_table32
[ bits >> 4 ][ 0 ] & eorx ) ^ bgx;
( (uint32_t *) dest )[ 1 ] =
( video_font_draw_table32
[ bits >> 4 ][ 1 ] & eorx ) ^ bgx;
( (uint32_t *) dest )[ 2 ] =
( video_font_draw_table32
[ bits >> 4 ][ 2 ] & eorx ) ^ bgx;
( (uint32_t *) dest )[ 3 ] =
( video_font_draw_table32
[ bits >> 4 ][ 3 ] & eorx ) ^ bgx;
( (uint32_t *) dest )[ 4 ] =
( video_font_draw_table32
[ bits & 15 ][ 0 ] & eorx ) ^ bgx;
( (uint32_t *) dest )[ 5 ] =
( video_font_draw_table32
[ bits & 15 ][ 1 ] & eorx ) ^ bgx;
( (uint32_t *) dest )[ 6 ] =
( video_font_draw_table32
[ bits & 15 ][ 2 ] & eorx ) ^ bgx;
( (uint32_t *) dest )[ 7 ] =
( video_font_draw_table32
[ bits & 15 ][ 3 ] & eorx ) ^ bgx;
}
}
#define ESC ( (char) 27 )
/* erase current location without moving the cursor */
#define BLANK ( (char) 0x7f )
static void videoPutChar( char ch )
{
switch ( ch ) {
case '\b': {
if ( column )
column--;
/* Move cursor on the previous location */
wr_cursor( row, column );
return;
}
case '\t': {
int i;
i = TAB_SPACE - ( column & ( TAB_SPACE - 1 ) );
while ( i-- ) {
video_drawchars( row, column, ' ' );
column += 1;
if ( column >= maxCol ) {
doCRNL( 1, 1 );
return;
}
}
wr_cursor( row, column );
return;
}
case '\n': {
doCRNL( 0, 1 );
return;
}
case 7: { /* Bell code must be inserted here */
return;
}
case '\r': {
doCRNL( 1, 0 );
return;
}
case BLANK: {
video_drawchars( row, column, ' ' );
wr_cursor( row, column );
return;
}
default: {
// *pt_bitmap = (unsigned char)ch | attribute;
video_drawchars( row, column, ch );
advanceCursor();
return;
}
}
}
/* trivial state machine to handle escape sequences:
*
* ---------------------------------
* | |
* | |
* KEY: esc V [ DCABHKJ esc |
* STATE: 0 -----> 27 -----> '[' ----------> -1 -----
* ^\ \ \ \
* KEY: | \other \ other \ other \ other
* <-------------------------------------
*
* in state '-1', the DCABHKJ cases are handled
*
* (cursor motion and screen clearing)
*/
#define DONE ( -1 )
static int handleEscape(
int oldState,
char ch
)
{
int rval = 0;
int ro, co;
switch ( oldState ) {
case DONE: /* means the previous char terminated an ESC sequence... */
case 0:
if ( 27 == ch ) {
rval = 27; /* START of an ESC sequence */
}
break;
case 27:
if ( '[' == ch ) {
rval = ch; /* received ESC '[', so far */
} else {
/* dump suppressed 'ESC'; outch will append the char */
videoPutChar( ESC );
}
break;
case '[':
/* handle 'ESC' '[' sequences here */
ro = row;
co = column;
rval = DONE; /* done */
switch ( ch ) {
case 'D': /* left */
if ( co > 0 )
co--;
break;
case 'C': /* right */
if ( co < maxCol )
co++;
break;
case 'A': /* up */
if ( ro > 0 )
ro--;
break;
case 'B': /* down */
if ( ro < maxRow )
ro++;
break;
case 'H': /* home */
ro = co = 0;
break;
case 'K': /* clear to end of line */
while ( column < maxCol - 1 )
videoPutChar( ' ' );
videoPutChar( BLANK );
break;
case 'J': /* clear to end of screen */
while ( ( ( row < maxRow - 1 ) || ( column < maxCol - 1 ) ) )
videoPutChar( ' ' );
videoPutChar( BLANK );
break;
default:
videoPutChar( ESC );
videoPutChar( '[' );
/* DONT move the cursor */
ro = -1;
rval = 0;
break;
}
// /* reset cursor */
if ( ro >= 0 )
gotorc( ro, co );
default:
break;
}
return rval;
}
static void clear_screen( void )
{
int i, j;
for ( j = 0; j < maxRow; j++ ) {
for ( i = 0; i < maxCol; i++ ) {
videoPutChar( ' ' );
}
}
column = 0;
row = 0;
}
void rpi_fb_outch( char c )
{
static int escaped = 0;
if ( !( escaped = handleEscape( escaped, c ) ) ) {
if ( '\n' == c )
videoPutChar( '\r' );
videoPutChar( c );
}
}
void rpi_video_init( void )
{
int ret = rpi_fb_init();
if ( ( ret != RPI_FB_INIT_OK ) &&
( ret != RPI_FB_INIT_ALREADY_INITIALIZED ) ) {
rpi_video_initialized = 0;
return;
}
struct fb_var_screeninfo fb_var_info;
struct fb_fix_screeninfo fb_fix_info;
rpi_get_var_screen_info( &fb_var_info );
rpi_get_fix_screen_info( &fb_fix_info );
maxCol = fb_var_info.xres / RPI_FONT_WIDTH;
maxRow = fb_var_info.yres / RPI_FONT_HEIGHT;
bytes_per_pixel = fb_var_info.bits_per_pixel / 8;
bytes_per_line = bytes_per_pixel * fb_var_info.xres;
bytes_per_char_line = RPI_FONT_HEIGHT * bytes_per_line;
fb_mem = RTEMS_DEVOLATILE( void *, fb_fix_info.smem_start );
column = 0;
row = 0;
nLines = 0;
fgx = ( CONSOLE_FG_COL << 24 ) |
( CONSOLE_FG_COL << 16 ) |
( CONSOLE_FG_COL << 8 ) |
CONSOLE_FG_COL;
bgx = ( CONSOLE_BG_COL << 24 ) |
( CONSOLE_BG_COL << 16 ) |
( CONSOLE_BG_COL << 8 ) |
CONSOLE_BG_COL;
eorx = fgx ^ bgx;
clear_screen();
rpi_video_initialized = 1;
}
int rpi_video_is_initialized( void )
{
return rpi_video_initialized;
}
/* for old DOS compatibility n-curses type of applications */
void gotoxy(
int x,
int y
);
int whereX( void );
int whereY( void );
void gotoxy(
int x,
int y
)
{
gotorc( y, x );
}
int whereX( void )
{
return row;
}
int whereY( void )
{
return column;
}

View File

@@ -1,167 +0,0 @@
/**
* @file
*
* @ingroup raspberrypi_usart
*
* @brief USART support.
*/
/*
* Copyright (c) 2013 Alan Cudmore
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
* http://www.rtems.org/license/LICENSE
*
*/
#include <libchip/sersupp.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <bsp/usart.h>
#include <bsp/raspberrypi.h>
#include <rtems/bspIo.h>
static void usart_delay(uint32_t n)
{
volatile uint32_t i = 0;
for(i = 0; i < n; i++)
;
}
#if 0
/*
* These will be useful when the driver supports interrupt driven IO.
*/
static rtems_vector_number usart_get_irq_number(const console_tbl *ct)
{
return ct->ulIntVector;
}
static uint32_t usart_get_baud(const console_tbl *ct)
{
return ct->ulClock;
}
#endif
static void usart_set_baud(int minor, int baud)
{
/*
* Nothing for now
*/
return;
}
static void usart_initialize(int minor)
{
unsigned int gpio_reg;
/*
** Program GPIO pins for UART 0
*/
gpio_reg = BCM2835_REG(BCM2835_GPIO_GPFSEL1);
gpio_reg &= ~(7<<12); /* gpio14 */
gpio_reg |= (4<<12); /* alt0 */
gpio_reg &= ~(7<<15); /* gpio15 */
gpio_reg |= (4<<15); /* alt0 */
BCM2835_REG(BCM2835_GPIO_GPFSEL1) = gpio_reg;
BCM2835_REG(BCM2835_GPIO_GPPUD) = 0;
usart_delay(150);
BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = (1<<14)|(1<<15);
usart_delay(150);
BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = 0;
/*
** Init the PL011 UART
*/
BCM2835_REG(BCM2835_UART0_CR) = 0;
BCM2835_REG(BCM2835_UART0_ICR) = 0x7FF;
BCM2835_REG(BCM2835_UART0_IMSC) = 0;
BCM2835_REG(BCM2835_UART0_IBRD) = 1;
BCM2835_REG(BCM2835_UART0_FBRD) = 40;
BCM2835_REG(BCM2835_UART0_LCRH) = 0x70;
BCM2835_REG(BCM2835_UART0_RSRECR) = 0;
BCM2835_REG(BCM2835_UART0_CR) = 0x301;
BCM2835_REG(BCM2835_UART0_IMSC) = BCM2835_UART0_IMSC_RX;
usart_set_baud(minor, 115000);
}
static int usart_first_open(int major, int minor, void *arg)
{
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;
const console_tbl *ct = Console_Port_Tbl [minor];
console_data *cd = &Console_Port_Data [minor];
cd->termios_data = tty;
rtems_termios_set_initial_baud(tty, ct->ulClock);
return 0;
}
static int usart_last_close(int major, int minor, void *arg)
{
return 0;
}
static int usart_read_polled(int minor)
{
if (minor == 0) {
if (((BCM2835_REG(BCM2835_UART0_FR)) & BCM2835_UART0_FR_RXFE) == 0) {
return((BCM2835_REG(BCM2835_UART0_DR)) & 0xFF );
} else {
return -1;
}
} else {
printk("Unknown console minor number: %d\n", minor);
return -1;
}
}
static void usart_write_polled(int minor, char c)
{
while (1) {
if ((BCM2835_REG(BCM2835_UART0_FR) & BCM2835_UART0_FR_TXFF) == 0)
break;
}
BCM2835_REG(BCM2835_UART0_DR) = c;
}
static ssize_t usart_write_support_polled(
int minor,
const char *s,
size_t n
)
{
ssize_t i = 0;
for (i = 0; i < n; ++i) {
usart_write_polled(minor, s [i]);
}
return n;
}
static int usart_set_attributes(int minor, const struct termios *term)
{
return -1;
}
const console_fns bcm2835_usart_fns = {
.deviceProbe = libchip_serial_default_probe,
.deviceFirstOpen = usart_first_open,
.deviceLastClose = usart_last_close,
.deviceRead = usart_read_polled,
.deviceWrite = usart_write_support_polled,
.deviceInitialize = usart_initialize,
.deviceWritePolled = usart_write_polled,
.deviceSetAttributes = usart_set_attributes,
.deviceOutputUsesInterrupts = false
};

View File

@@ -61,12 +61,12 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
librtemsbsp_a_SOURCES += ../shared/arm-gic-irq.c
# Console
librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
librtemsbsp_a_SOURCES += ../../shared/get-serial-mouse-ps2.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/getserialmouseps2.c
librtemsbsp_a_SOURCES += ../shared/arm-pl011.c
librtemsbsp_a_SOURCES += ../shared/arm-pl050.c
librtemsbsp_a_SOURCES += console/console-config.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/realview-pbx-a9/console/console-config.c
# Clock
librtemsbsp_a_SOURCES += ../shared/arm-a9mpcore-clock-config.c

View File

@@ -1,74 +0,0 @@
/*
* Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <info@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems/serial_mouse.h>
#include <rtems/bspIo.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <bsp/arm-pl011.h>
#include <bsp/arm-pl050.h>
#include <bsp/console-termios.h>
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)
{
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;
const console_device console_device_table[] = {
{
.device_file = "/dev/ttyS0",
.probe = pl011_probe,
.handler = &arm_pl011_fns,
.context = &pl011_context.base
}, {
.device_file = SERIAL_MOUSE_DEVICE_PS2,
.probe = console_device_probe_default,
.handler = &arm_pl050_fns,
.context = &pl050_context.base
}
};
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);

View File

@@ -33,7 +33,7 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/rtl22xx/clock/clockdrv.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
librtemsbsp_a_SOURCES += console/uart.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/rtl22xx/console/uart.c
# IRQ
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
librtemsbsp_a_SOURCES += irq/irq.c

View File

@@ -1,187 +0,0 @@
/**
* @file
* @ingroup rtl22xx_uart
* @brief UART support.
*/
#ifndef LPC22XX_UART_H
#define LPC22XX_UART_H
/**
* @defgroup rtl22xx_uart UART Support
* @ingroup arm_rtl22xx
* @brief UART (Universal Asynchronous Reciever/Transmitter) Support
* @{
*/
#define FIFODEEP 16
#define BD115200 115200
#define BD38400 38400
#define BD9600 9600
/** @brief PINSEL0 Value for UART0 */
#define U0_PINSEL (0x00000005)
/** @brief PINSEL0 Mask for UART0 */
#define U0_PINMASK (0x0000000F)
/** @brief PINSEL0 Value for UART1 */
#define U1_PINSEL (0x00050000)
/** @brief PINSEL0 Mask for UART1 */
#define U1_PINMASK (0x000F0000)
/**
* @name Uart line control register bit descriptions
* @{
*/
#define LCR_WORDLENTH_BIT 0
#define LCR_STOPBITSEL_BIT 2
#define LCR_PARITYENBALE_BIT 3
#define LCR_PARITYSEL_BIT 4
#define LCR_BREAKCONTROL_BIT 6
#define LCR_DLAB_BIT 7
/** @} */
/**
* @name Line Control Register bit definitions
* @{
*/
/** @brief 5-bit character length */
#define ULCR_CHAR_5 (0 << 0)
/** @brief 6-bit character length */
#define ULCR_CHAR_6 (1 << 0)
/** @brief 7-bit character length */
#define ULCR_CHAR_7 (2 << 0)
/** @brief 8-bit character length */
#define ULCR_CHAR_8 (3 << 0)
/** @brief no stop bits */
#define ULCR_STOP_0 (0 << 2)
/** @brief 1 stop bit */
#define ULCR_STOP_1 (1 << 2)
/** @brief No Parity */
#define ULCR_PAR_NO (0 << 3)
/** @brief Odd Parity */
#define ULCR_PAR_ODD (1 << 3)
/** @brief Even Parity */
#define ULCR_PAR_EVEN (3 << 3)
/** @brief MARK "1" Parity */
#define ULCR_PAR_MARK (5 << 3)
/** @brief SPACE "0" Paruty */
#define ULCR_PAR_SPACE (7 << 3)
/** @brief Output BREAK line condition */
#define ULCR_BREAK_ENABLE (1 << 6)
/** @brief Enable Divisor Latch Access */
#define ULCR_DLAB_ENABLE (1 << 7)
/** @} */
/**
* @name Modem Control Register bit definitions
* @{
*/
/** @brief Data Terminal Ready */
#define UMCR_DTR (1 << 0)
/** @brief Request To Send */
#define UMCR_RTS (1 << 1)
/** @brief Loopback */
#define UMCR_LB (1 << 4)
/** @} */
/**
* @name Line Status Register bit definitions
* @{
*/
/** @brief Receive Data Ready */
#define ULSR_RDR (1 << 0)
/** @brief Overrun Error */
#define ULSR_OE (1 << 1)
/** @brief Parity Error */
#define ULSR_PE (1 << 2)
/** @brief Framing Error */
#define ULSR_FE (1 << 3)
/** @brief Break Interrupt */
#define ULSR_BI (1 << 4)
/** @brief Transmit Holding Register Empty */
#define ULSR_THRE (1 << 5)
/** @brief Transmitter Empty */
#define ULSR_TEMT (1 << 6)
/** @brief Error in Receive FIFO */
#define ULSR_RXFE (1 << 7)
#define ULSR_ERR_MASK 0x1E
/** @} */
/**
* @name Modem Status Register bit definitions
* @{
*/
/** @brief Delta Clear To Send */
#define UMSR_DCTS (1 << 0)
/** @brief Delta Data Set Ready */
#define UMSR_DDSR (1 << 1)
/** @brief Trailing Edge Ring Indicator */
#define UMSR_TERI (1 << 2)
/** @brief Delta Data Carrier Detect */
#define UMSR_DDCD (1 << 3)
/** @brief Clear To Send */
#define UMSR_CTS (1 << 4)
/** @brief Data Set Ready */
#define UMSR_DSR (1 << 5)
/** @brief Ring Indicator */
#define UMSR_RI (1 << 6)
/** @brief Data Carrier Detect */
#define UMSR_DCD (1 << 7)
/** @} */
/**
* @name Uart Interrupt Identification
* @{
*/
#define IIR_RSL 0x3
#define IIR_RDA 0x2
#define IIR_CTI 0x6
#define IIR_THRE 0x1
/** @} */
/**
* @name Uart Interrupt Enable Type
* @{
*/
#define IER_RBR 0x1
#define IER_THRE 0x2
#define IER_RLS 0x4
/** @} */
/**
* @name Uart Receiver Errors
* @{
*/
#define RC_FIFO_OVERRUN_ERR 0x1
#define RC_OVERRUN_ERR 0x2
#define RC_PARITY_ERR 0x4
#define RC_FRAMING_ERR 0x8
#define RC_BREAK_IND 0x10
/** @} */
typedef enum {
UART0 = 0,
UART1
} LPC_UartChanel_t;
/** @} */
#endif

View File

@@ -1,283 +0,0 @@
/*
* console driver for RTL22xx UARTs
*
* If you want the driver to be interrupt driven, you
* need to write the ISR, and in the ISR insert the
* chars into termios's queue.
*/
/*
* Copyright (c) By ray <rayx.cn@gmail.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h> /* Must be before libio.h */
#include <rtems/libio.h>
#include <termios.h>
#include <rtems/bspIo.h>
/* Put the CPU (or UART) specific header file #include here */
#include <lpc22xx.h>
#include "lpc22xx_uart.h"
#include <libchip/serial.h>
#include <libchip/sersupp.h>
/* How many serial ports? */
#define NUM_DEVS 1
int dbg_dly;
/* static function prototypes */
static int uart_first_open(int major, int minor, void *arg);
static int uart_last_close(int major, int minor, void *arg);
static int uart_read(int minor);
static ssize_t uart_write(int minor, const char *buf, size_t len);
static void uart_init(int minor);
static void uart_write_polled(int minor, char c);
static int uart_set_attributes(int minor, const struct termios *t);
/* These are used by code in console.c */
unsigned long Console_Configuration_Count = NUM_DEVS;
/* Pointers to functions for handling the UART. */
const console_fns uart_fns = {
libchip_serial_default_probe,
uart_first_open,
uart_last_close,
uart_read,
uart_write,
uart_init,
uart_write_polled, /* not used in this driver */
uart_set_attributes,
FALSE /* TRUE if interrupt driven, FALSE if not. */
};
/*
* There's one item in array for each UART.
*
* Some of these fields are marked "NOT USED". They are not used
* by console.c, but may be used by drivers in libchip
*/
console_tbl Console_Configuration_Ports[] = {
{
"/dev/com0", /* sDeviceName */
SERIAL_CUSTOM, /* deviceType */
&uart_fns, /* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
0, /* ulMargin - NOT USED */
0, /* ulHysteresis - NOT USED */
NULL, /* pDeviceParams */
0, /* ulCtrlPort1 - NOT USED */
0, /* ulCtrlPort2 - NOT USED */
0, /* ulDataPort - NOT USED */
NULL, /* getRegister - NOT USED */
NULL, /* setRegister - NOT USED */
NULL, /* getData - NOT USED */
NULL, /* setData - NOT USED */
0, /* ulClock - NOT USED */
0 /* ulIntVector - NOT USED */
}
#if 0
{
"/dev/com1", /* sDeviceName */
SERIAL_CUSTOM, /* deviceType */
&uart_fns, /* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
0, /* ulMargin - NOT USED */
0, /* ulHysteresis - NOT USED */
NULL, /* pDeviceParams */
0, /* ulCtrlPort1 - NOT USED */
0, /* ulCtrlPort2 - NOT USED */
0, /* ulDataPort - NOT USED */
NULL, /* getRegister - NOT USED */
NULL, /* setRegister - NOT USED */
NULL, /* getData - NOT USED */
NULL, /* setData - NOT USED */
0, /* ulClock - NOT USED */
0 /* ulIntVector - NOT USED */
}
#endif
};
/*
* This is called the first time each device is opened. If the driver
* is interrupt driven, you should enable interrupts here. Otherwise,
* it's probably safe to do nothing.
*
* Since micromonitor already set up the UART, we do nothing.
*/
static int uart_first_open(int major, int minor, void *arg)
{
return 0;
}
/*
* This is called the last time each device is closed. If the driver
* is interrupt driven, you should disable interrupts here. Otherwise,
* it's probably safe to do nothing.
*/
static int uart_last_close(int major, int minor, void *arg)
{
return 0;
}
/*
* Read one character from UART.
*
* Return -1 if there's no data, otherwise return
* the character in lowest 8 bits of returned int.
*/
static int uart_read(int minor)
{
char c;
switch (minor) {
case 0:
if (U0LSR & ULSR_RDR) {
c = U0RBR;
return c;
}
return -1;
case 1:
if (U1LSR & ULSR_RDR) {
c = U1RBR;
return c;
}
return -1;
default:
break;
}
printk("Unknown console minor number %d\n", minor);
return -1;
}
/*
* Write buffer to UART
*
* return 1 on success, -1 on error
*/
static ssize_t uart_write(int minor, const char *buf, size_t len)
{
size_t i;
switch (minor) {
case 0:
for (i = 0; i < len; i++) {
while (!(U0LSR & ULSR_THRE)) /* wait for TX buffer to empty*/
continue; /* also either WDOG() or swap()*/
U0THR = (char) buf[i];
}
break;
case 1:
for (i = 0; i < len; i++) {
while (!(U0LSR & ULSR_THRE)) /* wait for TX buffer to empty*/
continue; /* also either WDOG() or swap()*/
U0THR = (char) buf[i];
}
break;
default:
printk("Unknown console minor number %d\n", minor);
return -1;
}
return len;
}
/* Set up the UART. */
static void uart_init(int minor)
{
#if 0 //init will be done in bspstart.c
int baud=6;
int mode =0x03;
if(minor==0){
// set port pins for UART0
PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
U0IER = 0x00; // disable all interrupts
// set the baudrate
U0LCR = 1<<7; // select divisor latches
U0DLL = (uint8_t)baud; // set for baud low byte
U0DLM = (uint8_t)(baud >> 8); // set for baud high byte
// set the number of characters and other
// user specified operating parameters
U0LCR = (mode & ~ULCR_DLAB_ENABLE);
U0FCR = mode>>8; /*fifo mode*/
// set port pins for UART1
PINSEL0 = (PINSEL0 & ~U1_PINMASK) | U1_PINSEL;
U1IER = 0x00; // disable all interrupts
}else if(minor==1){
// set the baudrate
U1LCR = ULCR_DLAB_ENABLE; // select divisor latches
U1DLL = (uint8_t)baud; // set for baud low byte
U1DLM = (uint8_t)(baud >> 8); // set for baud high byte
// set the number of characters and other
// user specified operating parameters
U1LCR = (mode & ~ULCR_DLAB_ENABLE);
U1FCR = mode>>8;/*fifo mode*/
}
#endif
}
/* I'm not sure this is needed for the shared console driver. */
static void uart_write_polled(int minor, char c)
{
uart_write(minor, &c, 1);
}
/* This is for setting baud rate, bits, etc. */
static int uart_set_attributes(int minor, const struct termios *t)
{
return 0;
}
/*
* Write a character to the console. This is used by printk() and
* maybe other low level functions. It should not use interrupts or any
* RTEMS system calls. It needs to be very simple
*/
static void _BSP_put_char( char c )
{
uart_write_polled(0, c);
}
BSP_output_char_function_type BSP_output_char = _BSP_put_char;
static int _BSP_get_char(void)
{
return uart_read(0);
}
BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;
/*
* init USART 0<><30>8 bit, 1 Stop,No checkout, BPS115200
*/
void UART0_Ini(void)
{
long Fdiv;
int i;
PINSEL0 = 0x00000005; // I/O to UART0
U0LCR = 0x83; // DLAB = 1
Fdiv = (Fpclk >>4) / UART_BPS; // configure BPS
U0DLM = Fdiv/256;
U0DLL = Fdiv%256;
U0LCR = 0x03;
for(i=0;i<10;i++){
U0THR = 67; //send a C to see if is OK
while ( (U0LSR&0x40)==0 );
}
}

View File

@@ -34,7 +34,7 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/smdk2410/clock/support.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
librtemsbsp_a_SOURCES += console/uart.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/smdk2410/console/uart.c
# IRQ
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
librtemsbsp_a_SOURCES += irq/irq.c

View File

@@ -1,242 +0,0 @@
/*
* console driver for S3C2400 UARTs
*
* This driver uses the shared console driver in
* ...../libbsp/shared/console.c
*
* If you want the driver to be interrupt driven, you
* need to write the ISR, and in the ISR insert the
* chars into termios's queue.
*
* Copyright (c) 2004 Cogent Computer Systems
* Written by Jay Monkman <jtm@lopingdog.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h> /* Must be before libio.h */
#include <rtems/libio.h>
#include <termios.h>
#include <rtems/bspIo.h>
/* Put the CPU (or UART) specific header file #include here */
#include <s3c24xx.h>
#include <libchip/serial.h>
#include <libchip/sersupp.h>
/* How many serial ports? */
#define NUM_DEVS 1
int uart_poll_read(int minor);
int dbg_dly;
/* static function prototypes */
static int uart_first_open(int major, int minor, void *arg);
static int uart_last_close(int major, int minor, void *arg);
static int uart_read(int minor);
static ssize_t uart_write(int minor, const char *buf, size_t len);
static void uart_init(int minor);
static void uart_write_polled(int minor, char c);
static int uart_set_attributes(int minor, const struct termios *t);
/* These are used by code in console.c */
unsigned long Console_Configuration_Count = NUM_DEVS;
/* Pointers to functions for handling the UART. */
const console_fns uart_fns =
{
libchip_serial_default_probe,
uart_first_open,
uart_last_close,
uart_read,
uart_write,
uart_init,
uart_write_polled, /* not used in this driver */
uart_set_attributes,
FALSE /* TRUE if interrupt driven, FALSE if not. */
};
/*
* There's one item in array for each UART.
*
* Some of these fields are marked "NOT USED". They are not used
* by console.c, but may be used by drivers in libchip
*
*/
console_tbl Console_Configuration_Ports[] = {
{
"/dev/com0", /* sDeviceName */
SERIAL_CUSTOM, /* deviceType */
&uart_fns, /* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
0, /* ulMargin - NOT USED */
0, /* ulHysteresis - NOT USED */
NULL, /* pDeviceParams */
0, /* ulCtrlPort1 - NOT USED */
0, /* ulCtrlPort2 - NOT USED */
0, /* ulDataPort - NOT USED */
NULL, /* getRegister - NOT USED */
NULL, /* setRegister - NOT USED */
NULL, /* getData - NOT USED */
NULL, /* setData - NOT USED */
0, /* ulClock - NOT USED */
0 /* ulIntVector - NOT USED */
}
};
/*********************************************************************/
/* Functions called via termios callbacks (i.e. the ones in uart_fns */
/*********************************************************************/
/*
* This is called the first time each device is opened. If the driver
* is interrupt driven, you should enable interrupts here. Otherwise,
* it's probably safe to do nothing.
*
* Since micromonitor already set up the UART, we do nothing.
*/
static int uart_first_open(int major, int minor, void *arg)
{
return 0;
}
/*
* This is called the last time each device is closed. If the driver
* is interrupt driven, you should disable interrupts here. Otherwise,
* it's probably safe to do nothing.
*/
static int uart_last_close(int major, int minor, void *arg)
{
return 0;
}
/*
* Read one character from UART.
*
* Return -1 if there's no data, otherwise return
* the character in lowest 8 bits of returned int.
*/
static int uart_read(int minor)
{
char c;
if (minor == 0) {
if (rUTRSTAT0 & 0x1) {
c = rURXH0 & 0xff;
return c;
} else {
return -1;
}
} else {
printk("Unknown console minor number: %d\n", minor);
return -1;
}
}
/*
* Write buffer to UART
*
* return 1 on success, -1 on error
*/
static ssize_t uart_write(int minor, const char *buf, size_t len)
{
int i;
if (minor == 0) {
for (i = 0; i < len; i++) {
/* Wait for fifo to have room */
while(!(rUTRSTAT0 & 0x2)) {
continue;
}
rUTXH0 = (char) buf[i];
}
} else {
printk("Unknown console minor number: %d\n", minor);
return -1;
}
return 1;
}
/* Set up the UART. */
static void uart_init(int minor)
{
int i;
unsigned int reg = 0;
/* enable UART0 */
rCLKCON|=0x100;
/* value is calculated so : (int)(PCLK/16./baudrate) -1 */
reg = get_PCLK() / (16 * 115200) - 1;
/* FIFO enable, Tx/Rx FIFO clear */
rUFCON0 = 0x07;
rUMCON0 = 0x0;
/* Normal,No parity,1 stop,8 bit */
rULCON0 = 0x3;
/*
* tx=level,rx=edge,disable timeout int.,enable rx error int.,
* normal,interrupt or polling
*/
rUCON0 = 0x245;
rUBRDIV0 = reg;
for (i = 0; i < 100; i++);
}
/* I'm not sure this is needed for the shared console driver. */
static void uart_write_polled(int minor, char c)
{
uart_write(minor, &c, 1);
}
/* This is for setting baud rate, bits, etc. */
static int uart_set_attributes(int minor, const struct termios *t)
{
return 0;
}
/***********************************************************************/
/*
* The following functions are not used by TERMIOS, but other RTEMS
* functions use them instead.
*/
/***********************************************************************/
/*
* Read from UART. This is used in the exit code, and can't
* rely on interrupts.
*/
int uart_poll_read(int minor)
{
return uart_read(minor);
}
/*
* Write a character to the console. This is used by printk() and
* maybe other low level functions. It should not use interrupts or any
* RTEMS system calls. It needs to be very simple
*/
static void _BSP_put_char( char c ) {
uart_write_polled(0, c);
}
BSP_output_char_function_type BSP_output_char = _BSP_put_char;
static int _BSP_get_char(void)
{
return uart_poll_read(0);
}
BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;

View File

@@ -56,8 +56,8 @@ librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq-dispatch.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
librtemsbsp_a_SOURCES += console/console-config.c
librtemsbsp_a_SOURCES += console/usart.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/stm32f4/console/console-config.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/stm32f4/console/usart.c
# I2C
librtemsbsp_a_SOURCES += i2c/i2c.c

View File

@@ -1,109 +0,0 @@
/*
* Copyright (c) 2012 Sebastian Huber. All rights reserved.
*
* embedded brains GmbH
* Obere Lagerstr. 30
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems/bspIo.h>
#include <libchip/serial.h>
#include <bspopts.h>
#include <bsp/irq.h>
#include <bsp/usart.h>
#include <bsp/stm32f4.h>
console_tbl Console_Configuration_Ports [] = {
#ifdef STM32F4_ENABLE_USART_1
{
.sDeviceName = "/dev/ttyS0",
.deviceType = SERIAL_CUSTOM,
.pDeviceFns = &stm32f4_usart_fns,
.ulCtrlPort1 = (uint32_t) STM32F4_USART_1,
.ulCtrlPort2 = 0,
.ulClock = STM32F4_USART_BAUD,
.ulIntVector = STM32F4_IRQ_USART1
},
#endif
#ifdef STM32F4_ENABLE_USART_2
{
.sDeviceName = "/dev/ttyS1",
.deviceType = SERIAL_CUSTOM,
.pDeviceFns = &stm32f4_usart_fns,
.ulCtrlPort1 = (uint32_t) STM32F4_USART_2,
.ulCtrlPort2 = 1,
.ulClock = STM32F4_USART_BAUD,
.ulIntVector = STM32F4_IRQ_USART2
},
#endif
#ifdef STM32F4_ENABLE_USART_3
{
.sDeviceName = "/dev/ttyS2",
.deviceType = SERIAL_CUSTOM,
.pDeviceFns = &stm32f4_usart_fns,
.ulCtrlPort1 = (uint32_t) STM32F4_USART_3,
.ulCtrlPort2 = 2,
.ulClock = STM32F4_USART_BAUD,
.ulIntVector = STM32F4_IRQ_USART3
},
#endif
#ifdef STM32F4_ENABLE_UART_4
{
.sDeviceName = "/dev/ttyS3",
.deviceType = SERIAL_CUSTOM,
.pDeviceFns = &stm32f4_usart_fns,
.ulCtrlPort1 = (uint32_t) STM32F4_USART_4,
.ulCtrlPort2 = 3,
.ulClock = STM32F4_USART_BAUD,
.ulIntVector = STM32F4_IRQ_UART4
},
#endif
#ifdef STM32F4_ENABLE_UART_5
{
.sDeviceName = "/dev/ttyS4",
.deviceType = SERIAL_CUSTOM,
.pDeviceFns = &stm32f4_usart_fns,
.ulCtrlPort1 = (uint32_t) STM32F4_USART_5,
.ulCtrlPort2 = 4,
.ulClock = STM32F4_USART_BAUD,
.ulIntVector = STM32F4_IRQ_UART5
},
#endif
#ifdef STM32F4_ENABLE_USART_6
{
.sDeviceName = "/dev/ttyS5",
.deviceType = SERIAL_CUSTOM,
.pDeviceFns = &stm32f4_usart_fns,
.ulCtrlPort1 = (uint32_t) STM32F4_USART_6,
.ulCtrlPort2 = 5,
.ulClock = STM32F4_USART_BAUD,
.ulIntVector = STM32F4_IRQ_USART6
},
#endif
};
#define PORT_COUNT \
(sizeof(Console_Configuration_Ports) \
/ sizeof(Console_Configuration_Ports [0]))
unsigned long Console_Configuration_Count = PORT_COUNT;
static void output_char(char c)
{
const console_fns *con =
Console_Configuration_Ports [Console_Port_Minor].pDeviceFns;
con->deviceWritePolled((int) Console_Port_Minor, c);
}
BSP_output_char_function_type BSP_output_char = output_char;
BSP_polling_getchar_function_type BSP_poll_char = NULL;

View File

@@ -1,214 +0,0 @@
/*
* Copyright (c) 2012 Sebastian Huber. All rights reserved.
*
* embedded brains GmbH
* Obere Lagerstr. 30
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <libchip/sersupp.h>
#include <bsp.h>
#include <bsp/io.h>
#include <bsp/rcc.h>
#include <bsp/irq.h>
#include <bsp/usart.h>
#include <bsp/stm32f4.h>
static volatile stm32f4_usart *usart_get_regs(const console_tbl *ct)
{
return (stm32f4_usart *) ct->ulCtrlPort1;
}
#if 0
static rtems_vector_number usart_get_irq_number(const console_tbl *ct)
{
return ct->ulIntVector;
}
#endif
static const stm32f4_rcc_index usart_rcc_index [] = {
STM32F4_RCC_USART1,
STM32F4_RCC_USART2,
STM32F4_RCC_USART3,
STM32F4_RCC_UART4,
STM32F4_RCC_UART5,
#ifdef STM32F4_FAMILY_F4XXXX
STM32F4_RCC_USART6
#endif /* STM32F4_FAMILY_F4XXXX */
};
static stm32f4_rcc_index usart_get_rcc_index(const console_tbl *ct)
{
return usart_rcc_index [ct->ulCtrlPort2];
}
static const uint8_t usart_pclk_index [] = { 1, 0, 0, 0, 0, 1 };
static const uint32_t usart_pclk_by_index [] = {
STM32F4_PCLK1,
STM32F4_PCLK2
};
static uint32_t usart_get_pclk(const console_tbl *ct)
{
return usart_pclk_by_index [usart_pclk_index [ct->ulCtrlPort2]];
}
static uint32_t usart_get_baud(const console_tbl *ct)
{
return ct->ulClock;
}
/*
* a = 8 * (2 - CR1[OVER8])
*
* usartdiv = div_mantissa + div_fraction / a
*
* baud = pclk / (a * usartdiv)
*
* usartdiv = pclk / (a * baud)
*
* Calculation in integer arithmetic:
*
* 1. div_mantissa = pclk / (a * baud)
*
* 2. div_fraction = pclk / (baud - a * div_mantissa)
*/
static uint32_t usart_get_bbr(
volatile stm32f4_usart *usart,
uint32_t pclk,
uint32_t baud
)
{
uint32_t a = 8 * (2 - ((usart->cr1 & STM32F4_USART_CR1_OVER8) != 0));
uint32_t div_mantissa_low = pclk / (a * baud);
uint32_t div_fraction_low = pclk / (baud - a * div_mantissa_low);
uint32_t div_mantissa_high;
uint32_t div_fraction_high;
uint32_t high_err;
uint32_t low_err;
uint32_t div_mantissa;
uint32_t div_fraction;
if (div_fraction_low < a - 1) {
div_mantissa_high = div_fraction_low;
div_fraction_high = div_fraction_low + 1;
} else {
div_mantissa_high = div_fraction_low + 1;
div_fraction_high = 0;
}
high_err = pclk - baud * (a * div_mantissa_high + div_fraction_high);
low_err = baud * (a * div_mantissa_low + div_fraction_low) - pclk;
if (low_err < high_err) {
div_mantissa = div_mantissa_low;
div_fraction = div_fraction_low;
} else {
div_mantissa = div_mantissa_high;
div_fraction = div_fraction_high;
}
return STM32F4_USART_BBR_DIV_MANTISSA(div_mantissa)
| STM32F4_USART_BBR_DIV_FRACTION(div_fraction);
}
static void usart_initialize(int minor)
{
const console_tbl *ct = Console_Port_Tbl [minor];
volatile stm32f4_usart *usart = usart_get_regs(ct);
uint32_t pclk = usart_get_pclk(ct);
uint32_t baud = usart_get_baud(ct);
stm32f4_rcc_index rcc_index = usart_get_rcc_index(ct);
stm32f4_rcc_set_clock(rcc_index, true);
usart->cr1 = 0;
usart->cr2 = 0;
usart->cr3 = 0;
usart->bbr = usart_get_bbr(usart, pclk, baud);
usart->cr1 = STM32F4_USART_CR1_UE
| STM32F4_USART_CR1_TE
| STM32F4_USART_CR1_RE;
}
static int usart_first_open(int major, int minor, void *arg)
{
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;
const console_tbl *ct = Console_Port_Tbl [minor];
console_data *cd = &Console_Port_Data [minor];
cd->termios_data = tty;
rtems_termios_set_initial_baud(tty, ct->ulClock);
return 0;
}
static int usart_last_close(int major, int minor, void *arg)
{
return 0;
}
static int usart_read_polled(int minor)
{
const console_tbl *ct = Console_Port_Tbl [minor];
volatile stm32f4_usart *usart = usart_get_regs(ct);
if ((usart->sr & STM32F4_USART_SR_RXNE) != 0) {
return STM32F4_USART_DR_GET(usart->dr);
} else {
return -1;
}
}
static void usart_write_polled(int minor, char c)
{
const console_tbl *ct = Console_Port_Tbl [minor];
volatile stm32f4_usart *usart = usart_get_regs(ct);
while ((usart->sr & STM32F4_USART_SR_TXE) == 0) {
/* Wait */
}
usart->dr = STM32F4_USART_DR(c);
}
static ssize_t usart_write_support_polled(
int minor,
const char *s,
size_t n
)
{
ssize_t i = 0;
for (i = 0; i < n; ++i) {
usart_write_polled(minor, s [i]);
}
return n;
}
static int usart_set_attributes(int minor, const struct termios *term)
{
return -1;
}
const console_fns stm32f4_usart_fns = {
.deviceProbe = libchip_serial_default_probe,
.deviceFirstOpen = usart_first_open,
.deviceLastClose = usart_last_close,
.deviceRead = usart_read_polled,
.deviceWrite = usart_write_support_polled,
.deviceInitialize = usart_initialize,
.deviceWritePolled = usart_write_polled,
.deviceSetAttributes = usart_set_attributes,
.deviceOutputUsesInterrupts = false
};

View File

@@ -62,9 +62,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
librtemsbsp_a_SOURCES += irq/irq.c
# Console
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
librtemsbsp_a_SOURCES += console/printk-support.c
librtemsbsp_a_SOURCES += console/tms570-sci.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/tms570/console/printk-support.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/tms570/console/tms570-sci.c
# Clock
librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/tms570/clock/clock.c

View File

@@ -1,126 +0,0 @@
/**
* @file printk-support.c
*
* @ingroup tms570
*
* @brief definitions of serial line for debugging.
*/
/*
* Copyright (c) 2014 Premysl Houdek <kom541000@gmail.com>
*
* Google Summer of Code 2014 at
* Czech Technical University in Prague
* Zikova 1903/4
* 166 36 Praha 6
* Czech Republic
*
* Based on LPC24xx and LPC1768 BSP
* by embedded brains GmbH and others
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems/bspIo.h>
#include <rtems/sysinit.h>
#include <stdint.h>
#include <string.h>
#include <bsp/tms570-sci.h>
#include <bsp/tms570-sci-driver.h>
#define TMS570_CONSOLE (&driver_context_table[0])
/**
* @brief Puts chars into peripheral
*
* debug functions always use serial dev 0 peripheral
*
* @retval Void
*/
static void tms570_debug_console_putc(char ch)
{
tms570_sci_context *ctx = TMS570_CONSOLE;
volatile tms570_sci_t *regs = ctx->regs;
rtems_interrupt_level level;
rtems_interrupt_disable(level);
while ( ( regs->FLR & TMS570_SCI_FLR_TXRDY ) == 0) {
rtems_interrupt_flash(level);
}
regs->TD = ch;
while ( ( regs->FLR & TMS570_SCI_FLR_TX_EMPTY ) == 0) {
rtems_interrupt_flash(level);
}
rtems_interrupt_enable(level);
}
/**
* @brief debug console output
*
* debug functions always use serial dev 0 peripheral
*
* @retval Void
*/
static void tms570_debug_console_out(char c)
{
tms570_debug_console_putc(c);
}
static void tms570_debug_console_init(void)
{
tms570_sci_context *ctx = TMS570_CONSOLE;
struct termios term;
tms570_sci_initialize(ctx);
memset(&term, 0, sizeof(term));
term.c_cflag = B115200;
tms570_sci_set_attributes(&ctx->base, &term);
BSP_output_char = tms570_debug_console_out;
}
static void tms570_debug_console_early_init(char c)
{
tms570_debug_console_init();
tms570_debug_console_out(c);
}
/**
* @brief debug console input
*
* debug functions always use serial dev 0 peripheral
*
* @retval x Read char
* @retval -1 No input character available
*/
static int tms570_debug_console_in( void )
{
tms570_sci_context *ctx = TMS570_CONSOLE;
volatile tms570_sci_t *regs = ctx->regs;
rtems_interrupt_level level;
int c;
rtems_interrupt_disable(level);
if ( regs->FLR & TMS570_SCI_FLR_RXRDY ) {
c = (unsigned char) regs->RD;
} else {
c = -1;
}
rtems_interrupt_enable(level);
return c;
}
BSP_output_char_function_type BSP_output_char =
tms570_debug_console_early_init;
BSP_polling_getchar_function_type BSP_poll_char = tms570_debug_console_in;
RTEMS_SYSINIT_ITEM(
tms570_debug_console_init,
RTEMS_SYSINIT_BSP_START,
RTEMS_SYSINIT_ORDER_LAST
);

View File

@@ -1,642 +0,0 @@
/**
* @file tms570-sci.c
*
* @ingroup tms570
*
* @brief Serial communication interface (SCI) functions definitions.
*/
/*
* Copyright (c) 2014 Premysl Houdek <kom541000@gmail.com>
*
* Google Summer of Code 2014 at
* Czech Technical University in Prague
* Zikova 1903/4
* 166 36 Praha 6
* Czech Republic
*
* Based on LPC24xx and LPC1768 BSP
* by embedded brains GmbH and others
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bspopts.h>
#include <termios.h>
#include <rtems/termiostypes.h>
#include <bsp/tms570-sci.h>
#include <bsp/tms570-sci-driver.h>
#include <rtems/console.h>
#include <bsp.h>
#include <bsp/fatal.h>
#include <bsp/irq.h>
#define TMS570_SCI_BUFFER_SIZE 1
/**
* @brief Table including all serial drivers
*
* Definitions of all serial drivers
*/
tms570_sci_context driver_context_table[] = {
{
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("TMS570 SCI1"),
.device_name = "/dev/console",
/* TMS570 UART peripheral use subset of LIN registers which are equivalent
* to SCI ones
*/
.regs = (volatile tms570_sci_t *) &TMS570_LIN,
.irq = TMS570_IRQ_SCI_LEVEL_0,
},
{
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("TMS570 SCI2"),
.device_name = "/dev/ttyS1",
.regs = &TMS570_SCI,
.irq = TMS570_IRQ_SCI2_LEVEL_0,
}
};
void tms570_sci_initialize(tms570_sci_context *ctx)
{
uint32_t rx_pin = 1 << 1;
uint32_t tx_pin = 1 << 2;
/* Resec SCI peripheral */
ctx->regs->GCR0 = TMS570_SCI_GCR0_RESET * 0;
ctx->regs->GCR0 = TMS570_SCI_GCR0_RESET * 1;
/* Clear all interrupt sources */
ctx->regs->CLEARINT = 0xffffffff;
/* Map all interrupts to SCI INT0 line */
ctx->regs->CLEARINTLVL = 0xffffffff;
ctx->regs->GCR1 = TMS570_SCI_GCR1_TXENA * 0 |
TMS570_SCI_GCR1_RXENA * 0 |
TMS570_SCI_GCR1_CONT * 0 | /* continue operation when debugged */
TMS570_SCI_GCR1_LOOP_BACK * 0 |
TMS570_SCI_GCR1_POWERDOWN * 0 |
TMS570_SCI_GCR1_SLEEP * 0 |
TMS570_SCI_GCR1_SWnRST * 0 | /* reset state */
TMS570_SCI_GCR1_CLOCK * 1 | /* internal clock */
TMS570_SCI_GCR1_TIMING_MODE * 1 |
TMS570_SCI_GCR1_COMM_MODE * 0;
/* Setup connection of SCI peripheral Rx and Tx pins */
ctx->regs->PIO0 = rx_pin * 1 | tx_pin * 1; /* Rx and Tx pins are not GPIO */
ctx->regs->PIO3 = rx_pin * 0 | tx_pin * 0; /* Default output low */
ctx->regs->PIO1 = rx_pin * 0 | tx_pin * 0; /* Input when not used by SCI */
ctx->regs->PIO6 = rx_pin * 0 | tx_pin * 0; /* No open drain */
ctx->regs->PIO7 = rx_pin * 0 | tx_pin * 0; /* Pull-up/down enabled */
ctx->regs->PIO8 = rx_pin * 1 | tx_pin * 1; /* Select pull-up */
/* Bring device out of software reset */
ctx->regs->GCR1 |= TMS570_SCI_GCR1_SWnRST;
}
/**
* @brief Serial drivers init function
*
* Initialize all serial drivers specified in driver_context_table
*
* @param[in] major
* @param[in] minor
* @param[in] arg
* @retval RTEMS_SUCCESSFUL Initialization completed
*/
rtems_device_driver console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code sc;
#if CONSOLE_USE_INTERRUPTS
const rtems_termios_device_handler *handler = &tms570_sci_handler_interrupt;
#else
const rtems_termios_device_handler *handler = &tms570_sci_handler_polled;
#endif
/*
* Initialize the Termios infrastructure. If Termios has already
* been initialized by another device driver, then this call will
* have no effect.
*/
rtems_termios_initialize();
/* Initialize each device */
for (
minor = 0;
minor < RTEMS_ARRAY_SIZE(driver_context_table);
++minor
) {
tms570_sci_context *ctx = &driver_context_table[minor];
tms570_sci_initialize(ctx);
/*
* Install this device in the file system and Termios. In order
* to use the console (i.e. being able to do printf, scanf etc.
* on stdin, stdout and stderr), one device must be registered as
* "/dev/console" (CONSOLE_DEVICE_NAME).
*/
sc = rtems_termios_device_install(
ctx->device_name,
handler,
NULL,
&ctx->base
);
if ( sc != RTEMS_SUCCESSFUL ) {
bsp_fatal(BSP_FATAL_CONSOLE_NO_DEV);
}
}
return RTEMS_SUCCESSFUL;
}
/**
* @brief Reads chars from HW
*
* Reads chars from HW peripheral specified in driver context.
* TMS570 does not have HW buffer for serial line so this function can
* return only 0 or 1 char
*
* @param[in] ctx context of the driver
* @param[out] buf read data buffer
* @param[in] N size of buffer
* @retval x Number of read chars from peripherals
*/
static int tms570_sci_read_received_chars(
tms570_sci_context * ctx,
char * buf,
int N)
{
if ( N < 1 ) {
return 0;
}
if ( ctx->regs->RD != 0 ) {
buf[0] = ctx->regs->RD;
return 1;
}
return 0;
}
/**
* @brief Enables RX interrupt
*
* Enables RX interrupt source of SCI peripheral
* specified in the driver context.
*
* @param[in] ctx context of the driver
* @retval Void
*/
static void tms570_sci_enable_interrupts(tms570_sci_context * ctx)
{
ctx->regs->SETINT = TMS570_SCI_SETINT_SET_RX_INT;
}
/**
* @brief Disables RX interrupt
*
* Disables RX interrupt source of SCI peripheral specified in the driver
* context.
*
* @param[in] ctx context of the driver
* @retval Void
*/
static void tms570_sci_disable_interrupts(tms570_sci_context * ctx)
{
ctx->regs->CLEARINT = TMS570_SCI_CLEARINT_CLR_RX_INT;
}
/**
* @brief Check whether driver has put char in HW
*
* Check whether driver has put char in HW.
* This information is read from the driver context not from a peripheral.
* TMS570 does not have write data buffer asociated with SCI
* so the return can be only 0 or 1.
*
* @param[in] ctx context of the driver
* @retval x
*/
static int tms570_sci_transmitted_chars(tms570_sci_context * ctx)
{
int ret;
ret = ctx->tx_chars_in_hw;
if ( ret == 1 ) {
ctx->tx_chars_in_hw = 0;
return 1;
}
return ret;
}
/**
* @brief Set attributes of the HW peripheral
*
* Sets attributes of the HW peripheral (parity, baud rate, etc.)
*
* @param[in] base context of the driver
* @param[in] t termios driver
* @retval true peripheral setting is changed
*/
bool tms570_sci_set_attributes(
rtems_termios_device_context *base,
const struct termios *t
)
{
tms570_sci_context *ctx = (tms570_sci_context *) base;
rtems_interrupt_lock_context lock_context;
int32_t bauddiv;
int32_t baudrate;
uint32_t flr_tx_ready = TMS570_SCI_FLR_TX_EMPTY;
/*
* Test for TMS570_SCI_FLR_TXRDY is not necessary
* because both SCITD and SCITXSHF has to be empty
* to TX_EMPTY be asserted. But there is no interrupt
* option for TX_EMPTY. Polling is used isntead.
*/
/* Baud rate */
baudrate = rtems_termios_baud_to_number(cfgetospeed(t));
rtems_termios_device_lock_acquire(base, &lock_context);
while ( (ctx->regs->GCR1 & TMS570_SCI_GCR1_TXENA) &&
(ctx->regs->FLR & flr_tx_ready) != flr_tx_ready) {
/*
* There are pending characters in the hardware,
* change in the middle of the character Tx leads
* to disturb of the character and SCI engine
*/
rtems_interval tw;
rtems_termios_device_lock_release(base, &lock_context);
tw = rtems_clock_get_ticks_per_second();
tw = tw * 5 / baudrate + 1;
rtems_task_wake_after( tw );
rtems_termios_device_lock_acquire(base, &lock_context);
}
ctx->regs->GCR1 &= ~( TMS570_SCI_GCR1_SWnRST | TMS570_SCI_GCR1_TXENA |
TMS570_SCI_GCR1_RXENA );
ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_STOP; /*one stop bit*/
ctx->regs->FORMAT = TMS570_SCI_FORMAT_CHAR(0x7);
switch ( t->c_cflag & ( PARENB|PARODD ) ) {
case ( PARENB|PARODD ):
/* Odd parity */
ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_PARITY;
ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY_ENA;
break;
case PARENB:
/* Even parity */
ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY;
ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY_ENA;
break;
default:
case 0:
case PARODD:
/* No Parity */
ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_PARITY_ENA;
}
/* Apply baudrate to the hardware */
baudrate *= 2 * 16;
bauddiv = (BSP_PLL_OUT_CLOCK + baudrate / 2) / baudrate;
ctx->regs->BRS = bauddiv;
ctx->regs->GCR1 |= TMS570_SCI_GCR1_SWnRST | TMS570_SCI_GCR1_TXENA |
TMS570_SCI_GCR1_RXENA;
rtems_termios_device_lock_release(base, &lock_context);
return true;
}
/**
* @brief sci interrupt handler
*
* Handler checks which interrupt occured and provides nessesary maintenance
* dequeue characters in termios driver whether character is send succesfully
* enqueue characters in termios driver whether character is recieved
*
* @param[in] arg rtems_termios_tty
* @retval Void
*/
static void tms570_sci_interrupt_handler(void * arg)
{
rtems_termios_tty *tty = arg;
tms570_sci_context *ctx = rtems_termios_get_device_context(tty);
char buf[TMS570_SCI_BUFFER_SIZE];
size_t n;
/*
* Check if we have received something.
*/
if ( (ctx->regs->FLR & TMS570_SCI_FLR_RXRDY ) == TMS570_SCI_FLR_RXRDY ) {
n = tms570_sci_read_received_chars(ctx, buf, TMS570_SCI_BUFFER_SIZE);
if ( n > 0 ) {
/* Hand the data over to the Termios infrastructure */
rtems_termios_enqueue_raw_characters(tty, buf, n);
}
}
/*
* Check if we have something transmitted.
*/
if ( (ctx->regs->FLR & TMS570_SCI_FLR_TXRDY ) == TMS570_SCI_FLR_TXRDY ) {
n = tms570_sci_transmitted_chars(ctx);
if ( n > 0 ) {
/*
* Notify Termios that we have transmitted some characters. It
* will call now the interrupt write function if more characters
* are ready for transmission.
*/
rtems_termios_dequeue_characters(tty, n);
}
}
}
/**
* @brief sci write function called from interrupt
*
* Nonblocking write function. Writes characters to HW peripheral
* TMS570 does not have write data buffer asociated with SCI
* so only one character can be written.
*
* @param[in] base context of the driver
* @param[in] buf buffer of characters pending to send
* @param[in] len size of the buffer
* @retval Void
*/
static void tms570_sci_interrupt_write(
rtems_termios_device_context *base,
const char *buf,
size_t len
)
{
tms570_sci_context *ctx = (tms570_sci_context *) base;
if ( len > 0 ) {
/* start UART TX, this will result in an interrupt when done */
ctx->regs->TD = *buf;
/* character written - raise count*/
ctx->tx_chars_in_hw = 1;
/* Enable TX interrupt (interrupt is edge-triggered) */
ctx->regs->SETINT = (1<<8);
} else {
/* No more to send, disable TX interrupts */
ctx->regs->CLEARINT = (1<<8);
/* Tell close that we sent everything */
}
}
/**
* @brief sci write function
*
* Blocking write function. Waits until HW peripheral is ready and then writes
* character to HW peripheral. Writes all characters in the buffer.
*
* @param[in] base context of the driver
* @param[in] buf buffer of characters pending to send
* @param[in] len size of the buffer
* @retval Void
*/
static void tms570_sci_poll_write(
rtems_termios_device_context *base,
const char *buf,
size_t n
)
{
tms570_sci_context *ctx = (tms570_sci_context *) base;
size_t i;
/* Write */
for ( i = 0; i < n; ++i ) {
while ( (ctx->regs->FLR & TMS570_SCI_FLR_TX_EMPTY ) == 0) {
;
}
ctx->regs->TD = buf[i];
}
}
/**
* @brief See if there is recieved charakter to read
*
* read the RX flag from peripheral specified in context
*
* @param[in] ctx context of the driver
* @retval 0 No character to read
* @retval x Character ready to read
*/
static int TMS570_sci_can_read_char(
tms570_sci_context * ctx
)
{
return ctx->regs->FLR & TMS570_SCI_FLR_RXRDY;
}
/**
* @brief reads character from peripheral
*
* reads the recieved character from peripheral specified in context
*
* @param[in] ctx context of the driver
* @retval x Character
*/
static char TMS570_sci_read_char(
tms570_sci_context * ctx
)
{
return ctx->regs->RD;
}
/**
* @brief sci read function
*
* check if there is recieved character to be read and reads it.
*
* @param[in] base context of the driver
* @retval -1 No character to be read
* @retval x Read character
*/
static int tms570_sci_poll_read(rtems_termios_device_context *base)
{
tms570_sci_context *ctx = (tms570_sci_context *) base;
/* Check if a character is available */
if ( TMS570_sci_can_read_char(ctx) ) {
return TMS570_sci_read_char(ctx);
} else {
return -1;
}
}
/**
* @brief initialization of the driver
*
* initialization of the HW peripheral specified in contex of the driver.
* This function is called only once when opening the driver.
*
* @param[in] tty Termios control
* @param[in] ctx context of the driver
* @param[in] term Termios attributes
* @param[in] args
* @retval false Error occured during initialization
* @retval true Driver is open and ready
*/
static bool tms570_sci_poll_first_open(
rtems_termios_tty *tty,
rtems_termios_device_context *ctx,
struct termios *term,
rtems_libio_open_close_args_t *args
)
{
bool ok;
rtems_termios_set_best_baud(term, TMS570_SCI_BAUD_RATE);
ok = tms570_sci_set_attributes(ctx, term);
if ( !ok ) {
return false;
}
return true;
}
/**
* @brief initialization of the interrupt driven driver
*
* calls tms570_sci_poll_first_open function.
* install and enables interrupts.
*
* @param[in] tty Termios control
* @param[in] base context of the driver
* @param[in] args
* @retval false Error occured during initialization
* @retval true Driver is open and ready
*/
static bool tms570_sci_interrupt_first_open(
rtems_termios_tty *tty,
rtems_termios_device_context *base,
struct termios *term,
rtems_libio_open_close_args_t *args
)
{
tms570_sci_context *ctx = (tms570_sci_context *) base;
rtems_status_code sc;
bool ret;
ret = tms570_sci_poll_first_open(tty, base, term, args);
if ( ret == false ) {
return false;
}
/* Register Interrupt handler */
sc = rtems_interrupt_handler_install(ctx->irq,
ctx->device_name,
RTEMS_INTERRUPT_SHARED,
tms570_sci_interrupt_handler,
tty
);
if ( sc != RTEMS_SUCCESSFUL ) {
return false;
}
tms570_sci_enable_interrupts(ctx);
return true;
}
/**
* @brief closes sci peripheral
*
* @param[in] tty Termios control
* @param[in] base context of the driver
* @param[in] args
* @retval false Error occured during initialization
* @retval true Driver is open and ready
*/
static void tms570_sci_poll_last_close(
rtems_termios_tty *tty,
rtems_termios_device_context *base,
rtems_libio_open_close_args_t *args
)
{
;
}
/**
* @brief closes sci peripheral of interrupt driven driver
*
* calls tms570_sci_poll_last_close and disables interrupts
*
* @param[in] tty Termios control
* @param[in] base context of the driver
* @param[in] args
* @retval false Error occured during initialization
* @retval true Driver is open and ready
*/
static void tms570_sci_interrupt_last_close(
rtems_termios_tty *tty,
rtems_termios_device_context *base,
rtems_libio_open_close_args_t *args
)
{
tms570_sci_context *ctx = (tms570_sci_context *) base;
rtems_interrupt_lock_context lock_context;
rtems_interval tw;
int32_t baudrate;
/* Turn off RX interrupts */
rtems_termios_device_lock_acquire(base, &lock_context);
tms570_sci_disable_interrupts(ctx);
rtems_termios_device_lock_release(base, &lock_context);
tw = rtems_clock_get_ticks_per_second();
baudrate = rtems_termios_baud_to_number(cfgetospeed(&tty->termios));
tw = tw * 10 / baudrate + 1;
while ( ( ctx->regs->FLR & TMS570_SCI_FLR_TX_EMPTY ) == 0 ) {
rtems_task_wake_after(tw);
}
/* uninstall ISR */
rtems_interrupt_handler_remove(ctx->irq, tms570_sci_interrupt_handler, tty);
tms570_sci_poll_last_close(tty, base, args);
}
/**
* @brief Struct containing definitions of polled driver functions.
*
* Encapsulates polled driver functions.
* Use of this table is determited by not defining TMS570_USE_INTERRUPTS
*/
const rtems_termios_device_handler tms570_sci_handler_polled = {
.first_open = tms570_sci_poll_first_open,
.last_close = tms570_sci_poll_last_close,
.poll_read = tms570_sci_poll_read,
.write = tms570_sci_poll_write,
.set_attributes = tms570_sci_set_attributes,
.mode = TERMIOS_POLLED
};
/**
* @brief Struct containing definitions of interrupt driven driver functions.
*
* Encapsulates interrupt driven driver functions.
* Use of this table is determited by defining TMS570_USE_INTERRUPTS
*/
const rtems_termios_device_handler tms570_sci_handler_interrupt = {
.first_open = tms570_sci_interrupt_first_open,
.last_close = tms570_sci_interrupt_last_close,
.poll_read = NULL,
.write = tms570_sci_interrupt_write,
.set_attributes = tms570_sci_set_attributes,
.mode = TERMIOS_IRQ_DRIVEN
};

View File

@@ -59,10 +59,10 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
librtemsbsp_a_SOURCES += ../shared/arm-gic-irq.c
# Console
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
librtemsbsp_a_SOURCES += console/console-config.c
librtemsbsp_a_SOURCES += console/debug-console.c
librtemsbsp_a_SOURCES += console/zynq-uart.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/console/console-config.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/console/debug-console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/console/zynq-uart.c
# Clock
librtemsbsp_a_SOURCES += ../shared/arm-a9mpcore-clock-config.c

View File

@@ -1,62 +0,0 @@
/*
* Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <info@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems/console.h>
#include <rtems/bspIo.h>
#include <bsp/irq.h>
#include <bsp/zynq-uart.h>
#include <bspopts.h>
zynq_uart_context zynq_uart_instances[2] = {
{
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 0" ),
.regs = (volatile struct zynq_uart *) 0xe0000000,
.irq = ZYNQ_IRQ_UART_0
}, {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 1" ),
.regs = (volatile struct zynq_uart *) 0xe0001000,
.irq = ZYNQ_IRQ_UART_1
}
};
rtems_status_code console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
size_t i;
rtems_termios_initialize();
for (i = 0; i < RTEMS_ARRAY_SIZE(zynq_uart_instances); ++i) {
char uart[] = "/dev/ttySX";
uart[sizeof(uart) - 2] = (char) ('0' + i);
rtems_termios_device_install(
&uart[0],
&zynq_uart_handler,
NULL,
&zynq_uart_instances[i].base
);
if (i == BSP_CONSOLE_MINOR) {
link(&uart[0], CONSOLE_DEVICE_NAME);
}
}
return RTEMS_SUCCESSFUL;
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems/bspIo.h>
#include <rtems/sysinit.h>
#include <bsp/zynq-uart.h>
#include <bspopts.h>
static void zynq_debug_console_out(char c)
{
rtems_termios_device_context *base =
&zynq_uart_instances[BSP_CONSOLE_MINOR].base;
zynq_uart_write_polled(base, c);
}
static void zynq_debug_console_init(void)
{
rtems_termios_device_context *base =
&zynq_uart_instances[BSP_CONSOLE_MINOR].base;
zynq_uart_initialize(base);
BSP_output_char = zynq_debug_console_out;
}
static void zynq_debug_console_early_init(char c)
{
rtems_termios_device_context *base =
&zynq_uart_instances[BSP_CONSOLE_MINOR].base;
zynq_uart_initialize(base);
zynq_debug_console_out(c);
}
static int zynq_debug_console_in(void)
{
rtems_termios_device_context *base =
&zynq_uart_instances[BSP_CONSOLE_MINOR].base;
return zynq_uart_read_polled(base);
}
BSP_output_char_function_type BSP_output_char = zynq_debug_console_early_init;
BSP_polling_getchar_function_type BSP_poll_char = zynq_debug_console_in;
RTEMS_SYSINIT_ITEM(
zynq_debug_console_init,
RTEMS_SYSINIT_BSP_START,
RTEMS_SYSINIT_ORDER_LAST
);

View File

@@ -1,315 +0,0 @@
/*
* Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <info@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp/zynq-uart.h>
#include <bsp/zynq-uart-regs.h>
#include <bsp/irq.h>
#include <bspopts.h>
/*
* Make weak and let the user override.
*/
uint32_t zynq_uart_input_clock(void) __attribute__ ((weak));
uint32_t zynq_uart_input_clock(void)
{
return ZYNQ_CLOCK_UART;
}
static int zynq_cal_baud_rate(uint32_t baudrate,
uint32_t* brgr,
uint32_t* bauddiv,
uint32_t modereg)
{
uint32_t brgr_value; /* Calculated value for baud rate generator */
uint32_t calcbaudrate; /* Calculated baud rate */
uint32_t bauderror; /* Diff between calculated and requested baud rate */
uint32_t best_error = 0xFFFFFFFF;
uint32_t percenterror;
uint32_t bdiv;
uint32_t inputclk = zynq_uart_input_clock();
/*
* Make sure the baud rate is not impossilby large.
* Fastest possible baud rate is Input Clock / 2.
*/
if ((baudrate * 2) > inputclk) {
return -1;
}
/*
* Check whether the input clock is divided by 8
*/
if(modereg & ZYNQ_UART_MODE_CLKS) {
inputclk = inputclk / 8;
}
/*
* Determine the Baud divider. It can be 4to 254.
* Loop through all possible combinations
*/
for (bdiv = 4; bdiv < 255; bdiv++) {
/*
* Calculate the value for BRGR register
*/
brgr_value = inputclk / (baudrate * (bdiv + 1));
/*
* Calculate the baud rate from the BRGR value
*/
calcbaudrate = inputclk/ (brgr_value * (bdiv + 1));
/*
* Avoid unsigned integer underflow
*/
if (baudrate > calcbaudrate) {
bauderror = baudrate - calcbaudrate;
}
else {
bauderror = calcbaudrate - baudrate;
}
/*
* Find the calculated baud rate closest to requested baud rate.
*/
if (best_error > bauderror) {
*brgr = brgr_value;
*bauddiv = bdiv;
best_error = bauderror;
}
}
/*
* Make sure the best error is not too large.
*/
percenterror = (best_error * 100) / baudrate;
#define XUARTPS_MAX_BAUD_ERROR_RATE 3 /* max % error allowed */
if (XUARTPS_MAX_BAUD_ERROR_RATE < percenterror) {
return -1;
}
return 0;
}
void zynq_uart_initialize(rtems_termios_device_context *base)
{
zynq_uart_context *ctx = (zynq_uart_context *) base;
volatile zynq_uart *regs = ctx->regs;
uint32_t brgr = 0x3e;
uint32_t bauddiv = 0x6;
zynq_cal_baud_rate(ZYNQ_UART_DEFAULT_BAUD, &brgr, &bauddiv, regs->mode);
regs->control &= ~(ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN);
regs->control = ZYNQ_UART_CONTROL_RXDIS
| ZYNQ_UART_CONTROL_TXDIS
| ZYNQ_UART_CONTROL_RXRES
| ZYNQ_UART_CONTROL_TXRES;
regs->mode = ZYNQ_UART_MODE_CHMODE(ZYNQ_UART_MODE_CHMODE_NORMAL)
| ZYNQ_UART_MODE_PAR(ZYNQ_UART_MODE_PAR_NONE)
| ZYNQ_UART_MODE_CHRL(ZYNQ_UART_MODE_CHRL_8);
regs->baud_rate_gen = ZYNQ_UART_BAUD_RATE_GEN_CD(brgr);
regs->baud_rate_div = ZYNQ_UART_BAUD_RATE_DIV_BDIV(bauddiv);
regs->rx_fifo_trg_lvl = ZYNQ_UART_RX_FIFO_TRG_LVL_RTRIG(0);
regs->rx_timeout = ZYNQ_UART_RX_TIMEOUT_RTO(0);
regs->control = ZYNQ_UART_CONTROL_RXEN
| ZYNQ_UART_CONTROL_TXEN
| ZYNQ_UART_CONTROL_RSTTO;
}
#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
static void zynq_uart_interrupt(void *arg)
{
rtems_termios_tty *tty = arg;
zynq_uart_context *ctx = rtems_termios_get_device_context(tty);
volatile zynq_uart *regs = ctx->regs;
uint32_t channel_sts;
if ((regs->irq_sts & (ZYNQ_UART_TIMEOUT | ZYNQ_UART_RTRIG)) != 0) {
regs->irq_sts = ZYNQ_UART_TIMEOUT | ZYNQ_UART_RTRIG;
do {
char c = (char) ZYNQ_UART_TX_RX_FIFO_FIFO_GET(regs->tx_rx_fifo);
rtems_termios_enqueue_raw_characters(tty, &c, 1);
channel_sts = regs->channel_sts;
} while ((channel_sts & ZYNQ_UART_CHANNEL_STS_REMPTY) == 0);
} else {
channel_sts = regs->channel_sts;
}
if (ctx->transmitting && (channel_sts & ZYNQ_UART_CHANNEL_STS_TEMPTY) != 0) {
rtems_termios_dequeue_characters(tty, 1);
}
}
#endif
static bool zynq_uart_first_open(
rtems_termios_tty *tty,
rtems_termios_device_context *base,
struct termios *term,
rtems_libio_open_close_args_t *args
)
{
#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
zynq_uart_context *ctx = (zynq_uart_context *) base;
volatile zynq_uart *regs = ctx->regs;
rtems_status_code sc;
#endif
rtems_termios_set_initial_baud(tty, ZYNQ_UART_DEFAULT_BAUD);
zynq_uart_initialize(base);
#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
regs->rx_timeout = 32;
regs->rx_fifo_trg_lvl = ZYNQ_UART_FIFO_DEPTH / 2;
regs->irq_dis = 0xffffffff;
regs->irq_sts = 0xffffffff;
regs->irq_en = ZYNQ_UART_RTRIG | ZYNQ_UART_TIMEOUT;
sc = rtems_interrupt_handler_install(
ctx->irq,
"UART",
RTEMS_INTERRUPT_SHARED,
zynq_uart_interrupt,
tty
);
if (sc != RTEMS_SUCCESSFUL) {
return false;
}
#endif
return true;
}
#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
static void zynq_uart_last_close(
rtems_termios_tty *tty,
rtems_termios_device_context *base,
rtems_libio_open_close_args_t *args
)
{
zynq_uart_context *ctx = (zynq_uart_context *) base;
rtems_interrupt_handler_remove(ctx->irq, zynq_uart_interrupt, tty);
}
#endif
int zynq_uart_read_polled(rtems_termios_device_context *base)
{
zynq_uart_context *ctx = (zynq_uart_context *) base;
volatile zynq_uart *regs = ctx->regs;
if ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_REMPTY) != 0) {
return -1;
} else {
return ZYNQ_UART_TX_RX_FIFO_FIFO_GET(regs->tx_rx_fifo);
}
}
void zynq_uart_write_polled(
rtems_termios_device_context *base,
char c
)
{
zynq_uart_context *ctx = (zynq_uart_context *) base;
volatile zynq_uart *regs = ctx->regs;
while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TFUL) != 0) {
/* Wait */
}
regs->tx_rx_fifo = ZYNQ_UART_TX_RX_FIFO_FIFO(c);
}
static void zynq_uart_write_support(
rtems_termios_device_context *base,
const char *buf,
size_t len
)
{
#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
zynq_uart_context *ctx = (zynq_uart_context *) base;
volatile zynq_uart *regs = ctx->regs;
if (len > 0) {
ctx->transmitting = true;
regs->irq_sts = ZYNQ_UART_TEMPTY;
regs->irq_en = ZYNQ_UART_TEMPTY;
regs->tx_rx_fifo = ZYNQ_UART_TX_RX_FIFO_FIFO(buf[0]);
} else {
ctx->transmitting = false;
regs->irq_dis = ZYNQ_UART_TEMPTY;
}
#else
ssize_t i;
for (i = 0; i < len; ++i) {
zynq_uart_write_polled(base, buf[i]);
}
#endif
}
static bool zynq_uart_set_attributes(
rtems_termios_device_context *context,
const struct termios *term
)
{
#if 0
volatile zynq_uart *regs = zynq_uart_get_regs(minor);
uint32_t brgr = 0;
uint32_t bauddiv = 0;
int rc;
rc = zynq_cal_baud_rate(115200, &brgr, &bauddiv, regs->mode);
if (rc != 0)
return rc;
regs->control &= ~(ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN);
regs->baud_rate_gen = ZYNQ_UART_BAUD_RATE_GEN_CD(brgr);
regs->baud_rate_div = ZYNQ_UART_BAUD_RATE_DIV_BDIV(bauddiv);
regs->control |= ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN;
return true;
#else
return false;
#endif
}
const rtems_termios_device_handler zynq_uart_handler = {
.first_open = zynq_uart_first_open,
.set_attributes = zynq_uart_set_attributes,
.write = zynq_uart_write_support,
#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
.last_close = zynq_uart_last_close,
.mode = TERMIOS_IRQ_DRIVEN
#else
.poll_read = zynq_uart_read_polled,
.mode = TERMIOS_POLLED
#endif
};
void zynq_uart_reset_tx_flush(zynq_uart_context *ctx)
{
volatile zynq_uart *regs = ctx->regs;
int c = 4;
while (c-- > 0)
zynq_uart_write_polled(&ctx->base, '\r');
while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TEMPTY) == 0) {
/* Wait */
}
}

View File

@@ -25,7 +25,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspgetworkarea-default.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c
librtemsbsp_a_SOURCES += console/console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/TLL6527M/console/console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/cache/cache.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/TLL6527M/start/interrupt.c

View File

@@ -1,181 +0,0 @@
/**
*@file console.c
*
*@brief
* - This file implements uart console for TLL6527M. TLL6527M has BF527 with
* second uart (uart-1) connected to the console.
*
* Target: TLL6527v1-0
* Compiler:
*
* COPYRIGHT (c) 2010 by ECE Northeastern University.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license
*
* @author Rohan Kangralkar, ECE, Northeastern University
* (kangralkar.r@husky.neu.edu)
*
* LastChange:
*/
#include <rtems.h>
#include <rtems/libio.h>
#include <bsp.h>
#include <rtems/bspIo.h>
#include <rtems/console.h>
#include <bsp/interrupt.h>
#include <libcpu/uart.h>
/***************************************************
LOCAL DEFINES
***************************************************/
/***************************************************
STATIC GLOBALS
***************************************************/
/**
* Declaration of UART
*/
static bfin_uart_channel_t channels[] = {
{"/dev/console",
UART1_BASE_ADDRESS,
DMA10_BASE_ADDRESS,
DMA11_BASE_ADDRESS,
CONSOLE_USE_INTERRUPTS,
UART_USE_DMA,
CONSOLE_BAUDRATE,
NULL,
0,
0}
};
/**
* Over all configuration
*/
static bfin_uart_config_t config = {
SCLK,
sizeof(channels) / sizeof(channels[0]),
channels
};
#if CONSOLE_USE_INTERRUPTS
/**
* The Rx and Tx isr will get the same argument
* The isr will have to find if it was the rx that caused the interrupt or
* the tx
*/
static bfin_isr_t bfinUARTISRs[] = {
#if UART_USE_DMA
/* For First uart */
{IRQ_DMA10_UART1_RX, bfinUart_rxDmaIsr, (void *)&channels[0], 0},
{IRQ_DMA11_UART1_TX, bfinUart_txDmaIsr, (void *)&channels[0], 0},
/* For second uart */
#else
/* For First uart */
{IRQ_DMA10_UART1_RX, bfinUart_rxIsr, &channels[0], 0},
{IRQ_DMA11_UART1_TX, bfinUart_txIsr, &channels[0], 0},
/* For second uart */
#endif
};
#endif
static void TLL6527_BSP_output_char(char c) {
bfin_uart_poll_write(0, c);
}
static int TLL6527_BSP_poll_char(void) {
return bfin_uart_poll_read(0);
}
BSP_output_char_function_type BSP_output_char = TLL6527_BSP_output_char;
BSP_polling_getchar_function_type BSP_poll_char = TLL6527_BSP_poll_char;
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);
}
/*
* Open entry point
*/
rtems_device_driver console_open(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg) {
return bfin_uart_open(major, minor, arg);
}
/**
*
* This routine initializes the console IO driver.
*
* Parameters
* @param major major number
* @param minor minor number
*
* Output parameters: NONE
*
* @return void
*/
rtems_device_driver console_initialize(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg) {
rtems_status_code status = RTEMS_NOT_DEFINED;
#if CONSOLE_USE_INTERRUPTS
int i = 0;
#endif
status = bfin_uart_initialize(major, &config);
if (status != RTEMS_SUCCESSFUL) {
rtems_fatal_error_occurred(status);
}
#if CONSOLE_USE_INTERRUPTS
for (i = 0; i < sizeof(bfinUARTISRs) / sizeof(bfinUARTISRs[0]); i++) {
bfin_interrupt_register(&bfinUARTISRs[i]);
#if INTERRUPT_USE_TABLE
#else
bfin_interrupt_enable(&bfinUARTISRs[i], 1);
#endif
}
#endif
return RTEMS_SUCCESSFUL;
}

View File

@@ -26,7 +26,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspgetworkarea-default.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c
librtemsbsp_a_SOURCES += console/console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/bf537Stamp/console/console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/cache/cache.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/interrupt.c

View File

@@ -1,141 +0,0 @@
/* Console driver for bf537Stamp
*/
/*
* Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA
* written by Allan Hessenflow <allanh@kallisti.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems.h>
#include <rtems/libio.h>
#include <bsp.h>
#include <rtems/bspIo.h>
#include <rtems/console.h>
#include <libcpu/bf537.h>
#include <libcpu/interrupt.h>
#include <libcpu/uart.h>
/*
#undef CONSOLE_USE_INTERRUPTS
#define CONSOLE_USE_INTERRUPTS 1
*/
static bfin_uart_channel_t channels[] = {
{"/dev/console",
UART0_BASE_ADDRESS,
0,
0,
CONSOLE_USE_INTERRUPTS,
0,
#ifdef CONSOLE_FORCE_BAUD
CONSOLE_FORCE_BAUD,
#else
0,
#endif
NULL,
0,
0}
#if (!BFIN_ON_SKYEYE)
,
{"/dev/tty1",
UART1_BASE_ADDRESS,
CONSOLE_USE_INTERRUPTS,
0,
NULL,
0}
#endif
};
static bfin_uart_config_t config = {
SCLK,
sizeof(channels) / sizeof(channels[0]),
channels
};
#if CONSOLE_USE_INTERRUPTS
static bfin_isr_t bfinUARTISRs[] = {
{SIC_DMA8_UART0_RX_VECTOR, bfinUart_rxIsr, 0, 0, NULL},
{SIC_DMA10_UART1_RX_VECTOR, bfinUart_rxIsr, 0, 0, NULL},
{SIC_DMA9_UART0_TX_VECTOR, bfinUart_txIsr, 0, 0, NULL},
{SIC_DMA11_UART1_TX_VECTOR, bfinUart_txIsr, 0, 0, NULL}
};
#endif
static void bf537Stamp_BSP_output_char(char c) {
bfin_uart_poll_write(0, c);
}
static int bf537Stamp_BSP_poll_char(void) {
return bfin_uart_poll_read(0);
}
BSP_output_char_function_type BSP_output_char = bf537Stamp_BSP_output_char;
BSP_polling_getchar_function_type BSP_poll_char = bf537Stamp_BSP_poll_char;
rtems_device_driver console_initialize(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg) {
rtems_status_code status;
#if CONSOLE_USE_INTERRUPTS
int i;
#endif
status = bfin_uart_initialize(major, &config);
#if CONSOLE_USE_INTERRUPTS
for (i = 0; i < sizeof(bfinUARTISRs) / sizeof(bfinUARTISRs[0]); i++) {
bfin_interrupt_register(&bfinUARTISRs[i]);
bfin_interrupt_enable(&bfinUARTISRs[i], TRUE);
}
#endif
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred(status);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver console_open(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg) {
return bfin_uart_open(major, minor, arg);
}
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);
}

View File

@@ -26,7 +26,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspgetworkarea-default.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c
librtemsbsp_a_SOURCES += console/console-io.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/eZKit533/console/console-io.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/cache/cache.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/interrupt.c

View File

@@ -1,126 +0,0 @@
/* console-io.c
*
* This file contains the hardware specific portions of the TTY driver
* for the serial ports for ezkit533.
*
* Copyright (c) 2006 by Atos Automacao Industrial Ltda.
* written by Alain Schaefer <alain.schaefer@easc.ch>
* and Antonio Giovanini <antonio@atos.com.br>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems.h>
#include <rtems/libio.h>
#include <bsp.h>
#include <rtems/bspIo.h>
#include <rtems/console.h>
#include <libcpu/bf533.h>
#include <libcpu/interrupt.h>
#include <libcpu/uart.h>
static bfin_uart_channel_t channels[] = {
{"/dev/console",
UART0_BASE_ADDRESS,
0,
0,
CONSOLE_USE_INTERRUPTS,
0,
#ifdef CONSOLE_FORCE_BAUD
CONSOLE_FORCE_BAUD,
#else
0,
#endif
NULL,
0,
0}
};
static bfin_uart_config_t config = {
SCLK,
sizeof(channels) / sizeof(channels[0]),
channels
};
#if CONSOLE_USE_INTERRUPTS
static bfin_isr_t bfinUARTISRs[] = {
{SIC_DMA6_UART0_RX_VECTOR, bfinUart_rxIsr, 0, 0, NULL},
{SIC_DMA7_UART0_TX_VECTOR, bfinUart_txIsr, 0, 0, NULL},
};
#endif
static void eZKit533_BSP_output_char(char c) {
bfin_uart_poll_write(0, c);
}
static int eZKit533_BSP_poll_char(void) {
return bfin_uart_poll_read(0);
}
BSP_output_char_function_type BSP_output_char = eZKit533_BSP_output_char;
BSP_polling_getchar_function_type BSP_poll_char = eZKit533_BSP_poll_char;
rtems_device_driver console_initialize(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg) {
rtems_status_code status;
#if CONSOLE_USE_INTERRUPTS
int i;
#endif
status = bfin_uart_initialize(major, &config);
#if CONSOLE_USE_INTERRUPTS
for (i = 0; i < sizeof(bfinUARTISRs) / sizeof(bfinUARTISRs[0]); i++) {
bfin_interrupt_register(&bfinUARTISRs[i]);
bfin_interrupt_enable(&bfinUARTISRs[i], TRUE);
}
#endif
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred(status);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver console_open(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg) {
return bfin_uart_open(major, minor, arg);
}
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);
}

View File

@@ -48,7 +48,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/clock/clock-simidle.c
librtemsbsp_a_SOURCES += timer/timer.c
# console
librtemsbsp_a_SOURCES += ../../shared/console-polled.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c
# IRQ
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
@@ -58,7 +58,7 @@ librtemsbsp_a_SOURCES += irq/irq.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/cache/nocache.c
# debugio
librtemsbsp_a_SOURCES += console/console-io.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/epiphany/epiphany_sim/console/console-io.c
include $(top_srcdir)/../../../../automake/local.am

View File

@@ -1,104 +0,0 @@
/*
* Copyright (c) 2015 University of York.
* Hesham ALMatary <hmka501@york.ac.uk>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <bsp.h>
#include <bsp/console-polled.h>
#include <rtems/libio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
static void outbyte_console( char );
static char inbyte_console( void );
void console_initialize_hardware(void)
{
/* Do nothing */
}
/* Epiphany simulator would handle this system call */
static void outbyte_console(char c)
{
register int chan asm("r0") = STDOUT_FILENO;
register void* addr asm("r1") = &c;
register int len asm("r2") = 1;
/* Invoke write system call to be handled by Epiphany simulator */
__asm__ __volatile__ ("trap 0" : : "r" (chan), "r" (addr), "r" (len));
}
static char inbyte_console(void)
{
char c;
register int chan asm("r0") = STDIN_FILENO;
register void* addr asm("r1") = &c;
register int len asm("r2") = 1;
/* Invoke read system call to be handled by Epiphany simulator */
asm ("trap 1" :: "r" (chan), "r" (addr), "r" (len));
return c;
}
/*
* console_outbyte_polled
*
* This routine transmits a character using polling.
*/
void console_outbyte_polled(
int port,
char ch
)
{
outbyte_console( ch );
}
/*
* console_inbyte_nonblocking
*
* This routine polls for a character.
*/
int console_inbyte_nonblocking(int port)
{
char c;
c = inbyte_console();
if (!c)
return -1;
return (int) c;
}
/*
* To support printk
*/
#include <rtems/bspIo.h>
static void Epiphany_output_char(char c) { console_outbyte_polled( 0, c ); }
BSP_output_char_function_type BSP_output_char = Epiphany_output_char;
BSP_polling_getchar_function_type BSP_poll_char =
(void *)console_inbyte_nonblocking;

View File

@@ -53,42 +53,42 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/i386/pc386/clock/todcfg.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/rtc/rtc-support.c
if RTEMS_VGA
librtemsbsp_a_SOURCES += console/inch.c
librtemsbsp_a_SOURCES += console/outch.c
librtemsbsp_a_SOURCES += console/defkeymap.c
librtemsbsp_a_SOURCES += console/keyboard.c
librtemsbsp_a_SOURCES += console/pc_keyb.c
librtemsbsp_a_SOURCES += console/ps2_mouse.c
librtemsbsp_a_SOURCES += console/vgainit.c
librtemsbsp_a_SOURCES += console/vt.c
librtemsbsp_a_SOURCES += console/videoAsm.S
librtemsbsp_a_SOURCES += console/kbd_parser.c
librtemsbsp_a_SOURCES += console/vgacons.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/inch.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/outch.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/defkeymap.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/keyboard.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/pc_keyb.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/ps2_mouse.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/vgainit.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/vt.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/videoAsm.S
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/kbd_parser.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/vgacons.c
if USE_VGA
librtemsbsp_a_SOURCES += console/fb_vga.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/fb_vga.c
endif
if USE_CIRRUS_GD5446
librtemsbsp_a_SOURCES += console/fb_cirrus.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/fb_cirrus.c
endif
if USE_VBE_RM
librtemsbsp_a_SOURCES += console/fb_vesa_rm.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/fb_vesa_rm.c
endif
endif
# console (non-graphics support)
librtemsbsp_a_SOURCES += console/serial_mouse_config.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/serial_mouse_config.c
librtemsbsp_a_SOURCES += ../shared/comm/uart.c
librtemsbsp_a_SOURCES += ../shared/comm/tty_drv.c
librtemsbsp_a_SOURCES += ../shared/realmode_int/realmode_int.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
librtemsbsp_a_SOURCES += console/console_select.c
librtemsbsp_a_SOURCES += console/console_control.c
librtemsbsp_a_SOURCES += console/conscfg.c
librtemsbsp_a_SOURCES += console/printk_support.c
librtemsbsp_a_SOURCES += console/exar17d15x.c
librtemsbsp_a_SOURCES += console/rtd316.c
librtemsbsp_a_SOURCES += console/uart_bus_pci.c
librtemsbsp_a_SOURCES += console/gdb_select.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/console_select.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/console_control.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/conscfg.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/printk_support.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/exar17d15x.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/rtd316.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/uart_bus_pci.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/gdb_select.c
# gdb
librtemsbsp_a_SOURCES += ../shared/comm/i386-stub.c

View File

@@ -1,198 +0,0 @@
/**
* @file
*
* This file contains the libchip configuration information
* to instantiate the libchip driver for the VGA console
* and serial ports on a PC.
*/
/*
* COPYRIGHT (c) 1989-2014, 2016.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <bsp/bspimpl.h>
#include <libchip/serial.h>
#include <libchip/ns16550.h>
#if BSP_ENABLE_VGA
#include <rtems/vgacons.h>
#endif
#include <bsp/irq.h>
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
#if BSP_ENABLE_VGA
#define VGA_CONSOLE_FUNCTIONS &vgacons_fns
#endif
#if BSP_ENABLE_COM1_COM4
#if 0
#define COM_CONSOLE_FUNCTIONS &ns16550_fns_polled
#else
#define COM_CONSOLE_FUNCTIONS &ns16550_fns
#endif
/*
* Base IO for UART
*/
#define COM1_BASE_IO 0x3F8
#define COM2_BASE_IO 0x3E8
#define COM3_BASE_IO 0x2F8
#define COM4_BASE_IO 0x2E8
#define CLOCK_RATE (115200 * 16)
static uint8_t com_get_register(uint32_t addr, uint8_t i)
{
register uint8_t val;
inport_byte( (addr + i), val );
return val;
}
static void com_set_register(uint32_t addr, uint8_t i, uint8_t val)
{
outport_byte( (addr + i), val );
}
#endif
/*
* Default to the PC VGA console if present and configured.
*/
console_tbl Console_Configuration_Ports[] = {
#if BSP_ENABLE_VGA
/*
* If present the VGA console must always be minor 0.
* See console_control.
*/
{
"/dev/vgacons", /* sDeviceName */
VGA_CONSOLE, /* deviceType */
VGA_CONSOLE_FUNCTIONS, /* pDeviceFns */
vgacons_probe, /* deviceProbe */
NULL, /* pDeviceFlow */
16, /* ulMargin */
8, /* ulHysteresis */
(void *) NULL, /* NULL */ /* pDeviceParams */
0x00000000, /* ulCtrlPort1 */
0x00000000, /* ulCtrlPort2 */
0x00000000, /* ulDataPort */
NULL, /* getRegister */
NULL, /* setRegister */
NULL,/* unused */ /* getData */
NULL,/* unused */ /* setData */
0x0, /* ulClock */
0x0 /* ulIntVector -- base for port */
},
#endif
};
unsigned long Console_Configuration_Count =
(sizeof(Console_Configuration_Ports)/sizeof(console_tbl));
static console_tbl Legacy_Ports[] = {
#if BSP_ENABLE_COM1_COM4
{
"/dev/com1", /* sDeviceName */
SERIAL_NS16550, /* deviceType */
COM_CONSOLE_FUNCTIONS, /* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
16, /* ulMargin */
8, /* ulHysteresis */
(void *) 9600, /* Baud Rate */ /* pDeviceParams */
COM1_BASE_IO, /* ulCtrlPort1 */
0x00000000, /* ulCtrlPort2 */
COM1_BASE_IO, /* ulDataPort */
com_get_register, /* getRegister */
com_set_register, /* setRegister */
NULL,/* unused */ /* getData */
NULL,/* unused */ /* setData */
CLOCK_RATE, /* ulClock */
BSP_UART_COM1_IRQ /* ulIntVector -- base for port */
},
{
"/dev/com2", /* sDeviceName */
SERIAL_NS16550, /* deviceType */
COM_CONSOLE_FUNCTIONS, /* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
16, /* ulMargin */
8, /* ulHysteresis */
(void *) 9600, /* Baud Rate */ /* pDeviceParams */
COM2_BASE_IO, /* ulCtrlPort1 */
0x00000000, /* ulCtrlPort2 */
COM2_BASE_IO, /* ulDataPort */
com_get_register, /* getRegister */
com_set_register, /* setRegister */
NULL,/* unused */ /* getData */
NULL,/* unused */ /* setData */
CLOCK_RATE, /* ulClock */
BSP_UART_COM2_IRQ /* ulIntVector -- base for port */
},
{
"/dev/com3", /* sDeviceName */
SERIAL_NS16550, /* deviceType */
COM_CONSOLE_FUNCTIONS, /* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
16, /* ulMargin */
8, /* ulHysteresis */
(void *) 9600, /* Baud Rate */ /* pDeviceParams */
COM3_BASE_IO, /* ulCtrlPort1 */
0x00000000, /* ulCtrlPort2 */
COM3_BASE_IO, /* ulDataPort */
com_get_register, /* getRegister */
com_set_register, /* setRegister */
NULL,/* unused */ /* getData */
NULL,/* unused */ /* setData */
CLOCK_RATE, /* ulClock */
BSP_UART_COM3_IRQ /* ulIntVector -- base for port */
},
{
"/dev/com4", /* sDeviceName */
SERIAL_NS16550, /* deviceType */
COM_CONSOLE_FUNCTIONS, /* pDeviceFns */
NULL, /* deviceProbe */
NULL, /* pDeviceFlow */
16, /* ulMargin */
8, /* ulHysteresis */
(void *) 9600, /* Baud Rate */ /* pDeviceParams */
COM4_BASE_IO, /* ulCtrlPort1 */
0x00000000, /* ulCtrlPort2 */
COM4_BASE_IO, /* ulDataPort */
com_get_register, /* getRegister */
com_set_register, /* setRegister */
NULL,/* unused */ /* getData */
NULL,/* unused */ /* setData */
CLOCK_RATE, /* ulClock */
BSP_UART_COM4_IRQ /* ulIntVector -- base for port */
},
#endif
};
#define Legacy_Port_Count \
(sizeof(Legacy_Ports)/sizeof(console_tbl))
void legacy_uart_probe(void)
{
#if BSP_ENABLE_COM1_COM4
const char *opt;
/*
* Check the command line to see if com1-com4 are disabled.
*/
opt = bsp_cmdline_arg("--disable-com1-com4");
if ( opt ) {
printk( "COM1-COM4: disabled\n" );
} else {
if (Legacy_Port_Count) {
printk("Legacy UART Ports: COM1-COM4\n");
console_register_devices( Legacy_Ports, Legacy_Port_Count );
}
}
#endif
}

View File

@@ -1,71 +0,0 @@
/*
* This file is an extension of the generic console driver
* shell used by all console drivers using libchip, it contains
* the console_control routine, This bsp needs its own version
* of this method to handle the keyboard and mouse as a single
* device.
*/
/*
* COPYRIGHT (c) 1989-2011.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <stdlib.h>
#include <assert.h>
#include <termios.h>
#include <rtems/libio.h>
#include <rtems/console.h>
#include <bsp/irq.h>
#include <rtems/termiostypes.h>
#include <libchip/serial.h>
#include <rtems/mouse_parser.h>
#if BSP_ENABLE_VGA
#include <rtems/keyboard.h>
#endif
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
/*
* console_control
*
* this routine uses the termios driver to process io
*/
rtems_device_driver console_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
#if BSP_ENABLE_VGA
if (minor == 0) {
rtems_libio_ioctl_args_t *args = arg;
switch (args->command) {
default:
if( vt_ioctl( args->command, (unsigned long)args->buffer ) != 0 )
return rtems_termios_ioctl (arg);
break;
case MW_UID_REGISTER_DEVICE:
printk( "SerialMouse: reg=%s\n", (const char*) args->buffer );
register_kbd_msg_queue( args->buffer, 0 );
break;
case MW_UID_UNREGISTER_DEVICE:
unregister_kbd_msg_queue( 0 );
break;
}
args->ioctl_return = 0;
return RTEMS_SUCCESSFUL;
}
#endif
return rtems_termios_ioctl (arg);
}

View File

@@ -1,250 +0,0 @@
/**
* @file
*
* @ingroup Console
*
* @brief pc386 console select
*
* This file contains a routine to select the console based upon a number
* of criteria.
*/
/*
* COPYRIGHT (c) 2011-2012, 2016.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <limits.h>
#include <stdlib.h>
#include <termios.h>
#include <bsp.h>
#include <libchip/serial.h>
#include <rtems/libio.h>
#include <rtems/console.h>
#include <rtems/termiostypes.h>
#include <bsp/bspimpl.h>
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
#ifdef RTEMS_RUNTIME_CONSOLE_SELECT
#include <crt.h>
#endif
/*
* Method to return true if the device associated with the
* minor number probs available.
*/
static bool bsp_Is_Available( rtems_device_minor_number minor )
{
console_tbl *cptr = Console_Port_Tbl[minor];
/*
* First perform the configuration dependent probe, then the
* device dependent probe
*/
if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) &&
cptr->pDeviceFns->deviceProbe(minor)) {
return true;
}
return false;
}
/*
* Method to return the first available device.
*/
static rtems_device_minor_number bsp_First_Available_Device( void )
{
rtems_device_minor_number minor;
for (minor=0; minor < Console_Port_Count ; minor++) {
console_tbl *cptr = Console_Port_Tbl[minor];
/*
* First perform the configuration dependent probe, then the
* device dependent probe
*/
if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) &&
cptr->pDeviceFns->deviceProbe(minor)) {
return minor;
}
}
/*
* Error No devices were found. We will want to bail here.
*/
rtems_fatal_error_occurred(RTEMS_IO_ERROR);
}
static bool parse_printk_or_console(
const char *param,
rtems_device_minor_number *minor_out
)
{
static const char *opt;
const char *option;
const char *comma;
size_t length;
size_t index;
rtems_device_minor_number minor;
console_tbl *conscfg;
/*
* Check the command line for the type of mode the console is.
*/
opt = bsp_cmdline_arg(param);
if ( !opt ) {
return false;
}
/*
* Fine the length, there can be more command line visible.
*/
length = 0;
while ((opt[length] != ' ') && (opt[length] != '\0')) {
++length;
if (length > NAME_MAX) {
printk("invalid option (%s): too long\n", param);
return false;
}
}
/*
* Only match up to a comma or NULL
*/
index = 0;
while ((opt[index] != '=') && (index < length)) {
++index;
}
if (opt[index] != '=') {
printk("invalid option (%s): no equals\n", param);
return false;
}
++index;
option = &opt[index];
while ((opt[index] != ',') && (index < length)) {
++index;
}
if (opt[index] == ',')
comma = &opt[index];
else
comma = NULL;
length = &opt[index] - option;
conscfg = console_find_console_entry( option, length, &minor );
if ( conscfg == NULL ) {
return false;
}
*minor_out = minor;
if (comma) {
option = comma + 1;
if (strncmp (option, "115200", sizeof ("115200") - 1) == 0)
conscfg->pDeviceParams = (void *)115200;
else if (strncmp (option, "57600", sizeof ("57600") - 1) == 0)
conscfg->pDeviceParams = (void *)57600;
else if (strncmp (option, "38400", sizeof ("38400") - 1) == 0)
conscfg->pDeviceParams = (void *)38400;
else if (strncmp (option, "19200", sizeof ("19200") - 1) == 0)
conscfg->pDeviceParams = (void *)19200;
else if (strncmp (option, "9600", sizeof ("9600") - 1) == 0)
conscfg->pDeviceParams = (void *)9600;
else if (strncmp (option, "4800", sizeof ("4800") - 1) == 0)
conscfg->pDeviceParams = (void *)4800;
}
return true;
}
/*
* Helper to retrieve device name
*/
static inline const char *get_name(
rtems_device_minor_number minor
)
{
return Console_Port_Tbl[minor]->sDeviceName;
}
/*
* Parse the arguments early so the printk and console ports are
* set appropriately.
*/
void pc386_parse_console_arguments(void)
{
rtems_device_minor_number minor;
rtems_device_minor_number minor_console = 0;
rtems_device_minor_number minor_printk = 0;
/*
* Assume that if only --console is specified, that printk() should
* follow that selection by default.
*/
if ( parse_printk_or_console( "--console=", &minor ) ) {
minor_console = minor;
minor_printk = minor;
}
/*
* But if explicitly specified, attempt to honor it.
*/
if ( parse_printk_or_console( "--printk=", &minor ) ) {
minor_printk = minor;
}
printk( "Console: %s printk: %s\n",
get_name(minor_console),get_name(minor_printk) );
/*
* Any output after this can cause problems until termios is initialised.
*/
Console_Port_Minor = minor_console;
BSPPrintkPort = minor_printk;
}
/*
* This handles the selection of the console after the devices are
* initialized.
*/
void bsp_console_select(void)
{
#ifdef RTEMS_RUNTIME_CONSOLE_SELECT
/*
* WARNING: This code is really needed any more and should be removed.
* references to COM1 and COM2 like they are wrong.
*/
if ( BSP_runtime_console_select )
BSP_runtime_console_select(&BSPPrintkPort, &Console_Port_Minor);
/*
* If no video card, fall back to serial port console
*/
if((Console_Port_Minor == BSP_CONSOLE_VGA)
&& (*(unsigned char*) NB_MAX_ROW_ADDR == 0)
&& (*(unsigned short*)NB_MAX_COL_ADDR == 0)) {
Console_Port_Minor = BSP_CONSOLE_COM2;
BSPPrintkPort = BSP_CONSOLE_COM1;
}
#endif
/*
* If the device that was selected isn't available then
* let the user know and select the first available device.
*/
if ( !bsp_Is_Available( Console_Port_Minor ) ) {
printk(
"Error finding %s setting console to first available\n",
get_name(Console_Port_Minor)
);
Console_Port_Minor = bsp_First_Available_Device();
}
}

View File

@@ -1,262 +0,0 @@
/* Do not edit this file! It was automatically generated by */
/* loadkeys --mktable defkeymap.map > defkeymap.c */
#include <sys/types.h>
#include <rtems/keyboard.h>
#include <rtems/kd.h>
u_short plain_map[NR_KEYS] = {
0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009,
0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c,
0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a,
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short shift_map[NR_KEYS] = {
0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009,
0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c,
0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a,
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short altgr_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200,
0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73,
0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200,
0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76,
0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510,
0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911,
0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b,
0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516,
0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short ctrl_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c,
0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a,
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short shift_ctrl_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013,
0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short alt_map[NR_KEYS] = {
0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809,
0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c,
0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907,
0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901,
0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a,
0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short ctrl_alt_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813,
0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a,
0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
ushort *key_maps[MAX_NR_KEYMAPS] = {
plain_map, shift_map, altgr_map, 0,
ctrl_map, shift_ctrl_map, 0, 0,
alt_map, 0, 0, 0,
ctrl_alt_map, 0
};
unsigned int keymap_count = 7;
/*
* Philosophy: most people do not define more strings, but they who do
* often want quite a lot of string space. So, we statically allocate
* the default and allocate dynamically in chunks of 512 bytes.
*/
char func_buf[] = {
'\033', '[', '[', 'A', 0,
'\033', '[', '[', 'B', 0,
'\033', '[', '[', 'C', 0,
'\033', '[', '[', 'D', 0,
'\033', '[', '[', 'E', 0,
'\033', '[', '1', '7', '~', 0,
'\033', '[', '1', '8', '~', 0,
'\033', '[', '1', '9', '~', 0,
'\033', '[', '2', '0', '~', 0,
'\033', '[', '2', '1', '~', 0,
'\033', '[', '2', '3', '~', 0,
'\033', '[', '2', '4', '~', 0,
'\033', '[', '2', '5', '~', 0,
'\033', '[', '2', '6', '~', 0,
'\033', '[', '2', '8', '~', 0,
'\033', '[', '2', '9', '~', 0,
'\033', '[', '3', '1', '~', 0,
'\033', '[', '3', '2', '~', 0,
'\033', '[', '3', '3', '~', 0,
'\033', '[', '3', '4', '~', 0,
'\033', '[', '1', '~', 0,
'\033', '[', '2', '~', 0,
'\033', '[', '3', '~', 0,
'\033', '[', '4', '~', 0,
'\033', '[', '5', '~', 0,
'\033', '[', '6', '~', 0,
'\033', '[', 'M', 0,
'\033', '[', 'P', 0,
};
char *funcbufptr = func_buf;
int funcbufsize = sizeof(func_buf);
int funcbufleft = 0; /* space left */
char *func_table[MAX_NR_FUNC] = {
func_buf + 0,
func_buf + 5,
func_buf + 10,
func_buf + 15,
func_buf + 20,
func_buf + 25,
func_buf + 31,
func_buf + 37,
func_buf + 43,
func_buf + 49,
func_buf + 55,
func_buf + 61,
func_buf + 67,
func_buf + 73,
func_buf + 79,
func_buf + 85,
func_buf + 91,
func_buf + 97,
func_buf + 103,
func_buf + 109,
func_buf + 115,
func_buf + 120,
func_buf + 125,
func_buf + 130,
func_buf + 135,
func_buf + 140,
func_buf + 145,
0,
0,
func_buf + 149,
0,
};
struct kbdiacr accent_table[MAX_DIACR] = {
{'`', 'A', '\300'}, {'`', 'a', '\340'},
{'\'', 'A', '\301'}, {'\'', 'a', '\341'},
{'^', 'A', '\302'}, {'^', 'a', '\342'},
{'~', 'A', '\303'}, {'~', 'a', '\343'},
{'"', 'A', '\304'}, {'"', 'a', '\344'},
{'O', 'A', '\305'}, {'o', 'a', '\345'},
{'0', 'A', '\305'}, {'0', 'a', '\345'},
{'A', 'A', '\305'}, {'a', 'a', '\345'},
{'A', 'E', '\306'}, {'a', 'e', '\346'},
{',', 'C', '\307'}, {',', 'c', '\347'},
{'`', 'E', '\310'}, {'`', 'e', '\350'},
{'\'', 'E', '\311'}, {'\'', 'e', '\351'},
{'^', 'E', '\312'}, {'^', 'e', '\352'},
{'"', 'E', '\313'}, {'"', 'e', '\353'},
{'`', 'I', '\314'}, {'`', 'i', '\354'},
{'\'', 'I', '\315'}, {'\'', 'i', '\355'},
{'^', 'I', '\316'}, {'^', 'i', '\356'},
{'"', 'I', '\317'}, {'"', 'i', '\357'},
{'-', 'D', '\320'}, {'-', 'd', '\360'},
{'~', 'N', '\321'}, {'~', 'n', '\361'},
{'`', 'O', '\322'}, {'`', 'o', '\362'},
{'\'', 'O', '\323'}, {'\'', 'o', '\363'},
{'^', 'O', '\324'}, {'^', 'o', '\364'},
{'~', 'O', '\325'}, {'~', 'o', '\365'},
{'"', 'O', '\326'}, {'"', 'o', '\366'},
{'/', 'O', '\330'}, {'/', 'o', '\370'},
{'`', 'U', '\331'}, {'`', 'u', '\371'},
{'\'', 'U', '\332'}, {'\'', 'u', '\372'},
{'^', 'U', '\333'}, {'^', 'u', '\373'},
{'"', 'U', '\334'}, {'"', 'u', '\374'},
{'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
{'T', 'H', '\336'}, {'t', 'h', '\376'},
{'s', 's', '\337'}, {'"', 'y', '\377'},
{'s', 'z', '\337'}, {'i', 'j', '\377'},
};
unsigned int accent_table_size = 68;

View File

@@ -1,224 +0,0 @@
/**
* @file
*
* @brief Driver for Exar XR17D15x Multiport UARTs
*
* This driver supports 2, 4 or 8 port Exar parts which are NS16550
* compatible.
*/
/*
* COPYRIGHT (c) 1989-2012.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <rtems/termiostypes.h>
#include <libchip/serial.h>
#include <libchip/ns16550.h>
#include <rtems/bspIo.h>
#include <rtems/pci.h>
#include <bsp/exar17d15x.h>
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
#define MAX_BOARDS 4
/*
* This is the rate for the clock internal to the parts.
*/
#define EXAR_CLOCK_RATE (921600*16)
/*
* Supported PCI Ids
*/
#define PCI_VENDOR_ID_EXAR 0x13A8
#define PCI_VENDOR_ID_EXAR_XR17D158 0x0158
#define PCI_VENDOR_ID_EXAR_XR17D154 0x0154
#define PCI_VENDOR_ID_EXAR_XR17D152 0x0152
/*
* Structure to manage each instance found.
*/
typedef struct {
uint16_t vendor;
uint16_t device;
uint8_t ports;
} exar_parts_t;
static exar_parts_t Supported[] = {
{ PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D158, 8 },
{ PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D154, 4 },
{ PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D152, 2 },
{ 0, 0, 0 }
};
/*
* Information saved from PCI scan
*/
typedef struct {
bool found;
uint32_t base;
uint8_t irq;
uint8_t bus;
uint8_t slot;
uint8_t ports;
} exar17d15x_conf_t;
/*
* Register Access Routines
*/
static uint8_t xr17d15x_get_register(uint32_t addr, uint8_t i)
{
uint8_t val = 0;
volatile uint8_t *reg = (volatile uint8_t *)(addr + i);
val = *reg;
// printk( "RD %p -> 0x%02x\n", reg, val );
return val;
}
static void xr17d15x_set_register(uint32_t addr, uint8_t i, uint8_t val)
{
volatile uint8_t *reg = (volatile uint8_t *)(addr + i);
// printk( "WR %p <- 0x%02x\n", reg, val );
*reg = val;
}
rtems_device_driver exar17d15x_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor_arg,
void *arg
)
{
// int pbus, pdev, pfun;
exar17d15x_conf_t conf[MAX_BOARDS];
int boards = 0;
int b = 0;
int p;
console_tbl *ports;
console_tbl *port_p;
int pbus;
int pdev;
int pfun;
int status;
int instance;
int i;
int total_ports = 0;
for ( b=0 ; b<MAX_BOARDS ; b++ ) {
conf[b].found = false;
}
/*
* Scan for Serial port boards
*
* NOTE: There appear to be Exar parts with 2 and 4 ports which would
* be easy to support. Just change the hard-coded 8 ports per
* board to variable and adjust.
*
* NOTE: There are likely other board vendors which could be supported
* by this.
*/
for ( instance=0 ; instance < MAX_BOARDS ; instance++ ) {
for ( i=0 ; Supported[i].ports != 0 ; i++ ) {
status = pci_find_device(
Supported[i].vendor,
Supported[i].device,
instance,
&pbus,
&pdev,
&pfun
);
if ( status == PCIB_ERR_SUCCESS ) {
boards++;
conf[instance].found = true;
conf[instance].ports = Supported[i].ports;
total_ports += conf[instance].ports;
break;
}
}
if ( status != PCIB_ERR_SUCCESS )
continue;
pci_read_config_byte(
pbus,
pdev,
pfun,
PCI_INTERRUPT_LINE,
&conf[instance].irq
);
pci_read_config_dword(
pbus,
pdev,
pfun,
PCI_BASE_ADDRESS_0,
&conf[instance].base
);
printk(
"Found Exar 17D15x %d at 0x%08lx IRQ %d with %d ports\n",
instance,
conf[instance].base,
conf[instance].irq,
conf[instance].ports
);
}
/*
* Now allocate array of device structures and fill them in
*/
ports = calloc( total_ports, sizeof( console_tbl ) );
port_p = ports;
for ( b=0 ; b<MAX_BOARDS ; b++ ) {
if ( conf[b].found == false )
continue;
for ( p=0 ; p<conf[b].ports ; p++ ) {
char name[32];
sprintf( name, "/dev/exar17d15x_%d_%d", b, p );
//printk("Found %s\n", name );
port_p->sDeviceName = strdup( name );
port_p->deviceType = SERIAL_NS16550;
#if 1
port_p->pDeviceFns = &ns16550_fns_polled;
#else
port_p->pDeviceFns = &ns16550_fns;
#endif
port_p->deviceProbe = NULL;
port_p->pDeviceFlow = NULL;
port_p->ulMargin = 16;
port_p->ulHysteresis = 8;
port_p->pDeviceParams = (void *) 9600;
port_p->ulCtrlPort1 = conf[b].base + (p * 0x0200);
port_p->ulCtrlPort2 = 0; /* NA */
port_p->ulDataPort = 0; /* NA */
port_p->getRegister = xr17d15x_get_register;
port_p->setRegister = xr17d15x_set_register;
port_p->getData = NULL; /* NA */
port_p->setData = NULL; /* NA */
port_p->ulClock = EXAR_CLOCK_RATE;
port_p->ulIntVector = conf[b].irq;
port_p++;
} /* end ports */
} /* end boards */
/*
* Register the devices
*/
if ( boards )
console_register_devices( ports, total_ports );
return RTEMS_SUCCESSFUL;
}

View File

@@ -1,766 +0,0 @@
/*
* FB driver for Cirrus GD5446 graphic hardware.
* Tested to be compatible with QEMU GD5446 emulation but not on real HW.
*
* Copyright (c) 2012 - Alexandru-Sever Horin (alex.sever.h@gmail.com).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* The code is based on next information sources:
* - CL-GD5446 Technical Reference Manual, 1996, Second Edition
* - RTEMS fb_vga.c - Rosimildo da Silva ( rdasilva@connecttel.com )
* - Cirrus xf86 driver - used as VGA hardware setup sequence documentation
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <pthread.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <rtems/libio.h>
#include <rtems/pci.h>
#include <rtems/fb.h>
#include <rtems/framebuffer.h>
#include <rtems/score/atomic.h>
/* flag to limit driver to protect against multiple opens */
static Atomic_Flag driver_mutex;
/* screen information for the VGA driver
* standard structures
*/
static struct fb_var_screeninfo fb_var;
static struct fb_fix_screeninfo fb_fix;
#define CIRRUS_VENDOR_ID 0x1013
#define CIRRUS_GD5446_DEVICE_ID 0x00b8
typedef struct _DisplayModeRec {
struct _DisplayModeRec *prev;
struct _DisplayModeRec *next;
char *name; /* identifier for the mode */
int type;
/* These are the values that the user sees/provides */
int Clock; /* pixel clock freq (kHz) */
int HDisplay; /* horizontal timing */
int HSyncStart;
int HSyncEnd;
int HTotal;
int HSkew;
int VDisplay; /* vertical timing */
int VSyncStart;
int VSyncEnd;
int VTotal;
int VScan;
int Flags;
/* These are the values the hardware uses */
int ClockIndex;
int SynthClock; /* Actual clock freq to
* be programmed (kHz) */
int CrtcHDisplay;
int CrtcHBlankStart;
int CrtcHSyncStart;
int CrtcHSyncEnd;
int CrtcHBlankEnd;
int CrtcHTotal;
int CrtcHSkew;
int CrtcVDisplay;
int CrtcVBlankStart;
int CrtcVSyncStart;
int CrtcVSyncEnd;
int CrtcVBlankEnd;
int CrtcVTotal;
int CrtcHAdjusted;
int CrtcVAdjusted;
int PrivSize;
int32_t *Private;
int PrivFlags;
float HSync, VRefresh;
} DisplayModeRec, *DisplayModePtr;
static DisplayModeRec available_modes[] = {
{
.Clock = 31500 ,
.HDisplay = 640 ,
.HSyncStart = 664 ,
.HSyncEnd = 704 ,
.HTotal = 832 ,
.HSkew = 0 ,
.VDisplay = 480 , /* vertical timing */
.VSyncStart = 489 ,
.VSyncEnd = 491 ,
.VTotal = 520 ,
.VScan = 0,
.Flags = 0
},
{
.Clock = 40000 ,
.HDisplay = 800 ,
.HSyncStart = 840 ,
.HSyncEnd = 968 ,
.HTotal = 1056 ,
.HSkew = 0 ,
.VDisplay = 600 , /* vertical timing */
.VSyncStart = 601 ,
.VSyncEnd = 605 ,
.VTotal = 628 ,
.VScan = 0,
.Flags = 0
},
};
static DisplayModePtr active_mode;
/* The display mode used for the board hardcoded in the following define
* Index in above structure
*/
#define CIRRUS_DISPLAY_MODE 0
/* The display bytes per pixel used for the board hardcoded in the following define
* Index in above structure
*/
#define CIRRUS_DEFAULT_BPP 24
/* cirrus board information */
struct cirrus_board_str{
int pci_bus;
int pci_device;
int pci_function;
void *reg_base;
};
static struct cirrus_board_str cirrus_board_info;
/*
* get information from the board
*/
static int
cirrus_pci_read( struct cirrus_board_str *cirrus_board, uint32_t *mem_base, uint32_t *cirrus_register_base)
{
int r;
r = pci_read_config_dword(
cirrus_board->pci_bus, cirrus_board->pci_device, cirrus_board->pci_function,
PCI_BASE_ADDRESS_0, mem_base);
if( r != PCIB_ERR_SUCCESS)
return RTEMS_UNSATISFIED;
r = pci_read_config_dword(
cirrus_board->pci_bus, cirrus_board->pci_device, cirrus_board->pci_function,
PCI_BASE_ADDRESS_1, cirrus_register_base);
if( r != PCIB_ERR_SUCCESS)
return RTEMS_UNSATISFIED;
*mem_base &= PCI_BASE_ADDRESS_MEM_MASK;
*cirrus_register_base &= PCI_BASE_ADDRESS_MEM_MASK;
return RTEMS_SUCCESSFUL;
}
static inline int
fb_cirrus_read_config_dword(
struct cirrus_board_str *fbst,
unsigned char where,
uint32_t *pval)
{
return pci_read_config_dword(
fbst->pci_bus, fbst->pci_device, fbst->pci_function,
where, pval);
}
static inline int
fb_cirrus_write_config_dword(
struct cirrus_board_str *fbst,
unsigned char where,
uint32_t val)
{
return pci_write_config_dword(
fbst->pci_bus, fbst->pci_device, fbst->pci_function,
where, val);
}
static inline void
fb_cirrus_write_reg8 (
const struct cirrus_board_str *fbst,
unsigned int reg,
unsigned int val)
{
*(volatile uint8_t*)((char *)fbst->reg_base + reg) = val;
}
static inline unsigned int
fb_cirrus_read_reg8 (
const struct cirrus_board_str *fbst,
unsigned int reg)
{
return *(volatile uint8_t*)((char *)fbst->reg_base + reg);
}
#define SEQ_INDEX 0x04
#define SEQ_DATA 0x05
static inline void
fb_cirrus_write_seq_reg (
const struct cirrus_board_str *fbst,
unsigned int reg,
unsigned int val)
{
fb_cirrus_write_reg8(fbst, SEQ_INDEX, reg);
fb_cirrus_write_reg8(fbst, SEQ_DATA, val);
}
static inline unsigned int
fb_cirrus_read_seq_reg (
const struct cirrus_board_str *fbst,
unsigned int reg)
{
fb_cirrus_write_reg8(fbst, SEQ_INDEX, reg);
return fb_cirrus_read_reg8(fbst, SEQ_DATA);
}
#define CRT_INDEX 0x14
#define CRT_DATA 0x15
static inline void
fb_cirrus_write_crt_reg (
const struct cirrus_board_str *fbst,
unsigned int reg,
unsigned int val)
{
fb_cirrus_write_reg8(fbst, CRT_INDEX, reg);
fb_cirrus_write_reg8(fbst, CRT_DATA, val);
}
static inline unsigned int
fb_cirrus_read_crt_reg (
const struct cirrus_board_str *fbst,
unsigned int reg)
{
fb_cirrus_write_reg8(fbst, CRT_INDEX, reg);
return fb_cirrus_read_reg8(fbst, CRT_DATA);
}
#define GDC_INDEX 0x0E
#define GDC_DATA 0x0F
static inline void
fb_cirrus_write_gdc_reg (
const struct cirrus_board_str *fbst,
unsigned int reg,
unsigned int val)
{
fb_cirrus_write_reg8(fbst, GDC_INDEX, reg);
fb_cirrus_write_reg8(fbst, GDC_DATA, val);
}
static inline unsigned int
fb_cirrus_read_gdc_reg (
const struct cirrus_board_str *fbst,
unsigned int reg)
{
fb_cirrus_write_reg8(fbst, GDC_INDEX, reg);
return fb_cirrus_read_reg8(fbst, GDC_DATA);
}
#define VGA_DAC_MASK 0x06
static inline void
fb_cirrus_write_hdr_reg (
const struct cirrus_board_str *fbst,
unsigned int val)
{
volatile unsigned int dummy RTEMS_UNUSED;
dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK);
dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK);
dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK);
dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK);
fb_cirrus_write_reg8(fbst, VGA_DAC_MASK, val);
}
/* Functionality to support multiple VGA frame buffers can be added easily,
* but is not supported at this moment because there is no need for two or
* more "classic" VGA adapters. Multiple frame buffer drivers may be
* implemented and If we had implement it they would be named as "/dev/fb0",
* "/dev/fb1", "/dev/fb2" and so on.
*/
/*
* fb_cirrus device driver INITIALIZE entry point.
*/
rtems_device_driver
frame_buffer_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code status;
int res;
printk( "FB_CIRRUS -- driver initializing..\n" );
res = pci_find_device(
CIRRUS_VENDOR_ID,
CIRRUS_GD5446_DEVICE_ID,
minor,
&cirrus_board_info.pci_bus,
&cirrus_board_info.pci_device,
&cirrus_board_info.pci_function
);
if ( res != PCIB_ERR_SUCCESS ) {
printk( "FB_CIRRUS initialize -- device not found\n" );
return RTEMS_UNSATISFIED;
}
else{
printk( "FB_CIRRUS -- driver initializing..\n" );
/*
* Register the device
*/
status = rtems_io_register_name (FRAMEBUFFER_DEVICE_0_NAME, major, 0);
if (status != RTEMS_SUCCESSFUL) {
printk("Error registering " FRAMEBUFFER_DEVICE_0_NAME
" FB_CIRRUS framebuffer device!\n");
rtems_fatal_error_occurred( status );
}
_Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE);
return RTEMS_SUCCESSFUL;
}
}
/*
* This function is used to initialize the Start Address - the first
* displayed location in the video memory.
* Usually mandatory
*/
static void
cirrus_adjust_frame( struct cirrus_board_str *board, int x, int y)
{
uint32_t Base;
uint8_t tmp;
Base = ((y * fb_var.xres + x) >> 3);
if (fb_var.bits_per_pixel != 1)
Base *= (fb_var.bits_per_pixel >> 2);
printk("FB_CIRRUS: cirrus_adjust_frame %d %d >>> %d %x\n", x, y, Base, Base);
if ((Base & ~0x000FFFFF) != 0) {
printk("FB_CIRRUS: Internal error: cirrus_adjust_frame: cannot handle overflow\n");
return;
}
fb_cirrus_write_crt_reg( board, 0x0C, (Base >> 8) & 0xff);
fb_cirrus_write_crt_reg( board, 0x0D, Base & 0xff);
tmp = fb_cirrus_read_crt_reg( board, 0x1B);
tmp &= 0xF2;
tmp |= (Base >> 16) & 0x01;
tmp |= (Base >> 15) & 0x0C;
fb_cirrus_write_crt_reg( board, 0x1B, tmp);
tmp = fb_cirrus_read_crt_reg( board, 0x1D);
tmp &= 0x7F;
tmp |= (Base >> 12) & 0x80;
fb_cirrus_write_crt_reg( board, 0x1D, tmp);
}
static int
cirrus_set_mode(DisplayModePtr mode)
{
int depthcode = fb_var.bits_per_pixel;;
int width;
int HDiv2 = 0, VDiv2 = 0;
const struct cirrus_board_str *cirrus_board_ptr = &cirrus_board_info;
int temp;
int hdr = -1;
printk("FB_CIRRUS: mode %d bpp, %d Hz %d %d %d %d %d %d %d %d\n",
fb_var.bits_per_pixel,
mode->Clock,
mode->HDisplay,
mode->HSyncStart,
mode->HSyncEnd,
mode->HTotal,
mode->VDisplay,
mode->VSyncStart,
mode->VSyncEnd,
mode->VTotal);
if ( mode->Clock > 85500 ) {
/* The actual DAC register value is set later. */
/* The CRTC is clocked at VCLK / 2, so we must half the */
/* horizontal timings. */
if (!mode->CrtcHAdjusted) {
mode->HDisplay >>= 1;
mode->HSyncStart >>= 1;
mode->HTotal >>= 1;
mode->HSyncEnd >>= 1;
mode->SynthClock >>= 1;
mode->CrtcHAdjusted = TRUE;
}
depthcode += 64;
HDiv2 = 1;
}
if (mode->VTotal >= 1024 ) {
/* For non-interlaced vertical timing >= 1024, the vertical timings */
/* are divided by 2 and VGA CRTC 0x17 bit 2 is set. */
if (!mode->CrtcVAdjusted) {
mode->VDisplay >>= 1;
mode->VSyncStart >>= 1;
mode->VSyncEnd >>= 1;
mode->VTotal >>= 1;
mode->CrtcVAdjusted = TRUE;
}
VDiv2 = 1;
}
/****************************************************
* Sequential registers
*/
fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x00, 0x00);
fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x01, 0x01);
fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x02, 0x0F);
fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x03, 0x00);
fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x04, 0x0E);
/****************************************************
* CRTC Controller Registers
*/
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x00, (mode->HTotal >> 3) - 5 );
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x01, (mode->HDisplay >> 3) - 1);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x02, (mode->HSyncStart >> 3) - 1);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x03, ((mode->HSyncEnd >> 3) & 0x1F) | 0x80);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x04, (mode->HSyncStart >> 3));
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x05,
(((mode->HSyncEnd >> 3) & 0x20 ) << 2 )
| (((mode->HSyncEnd >> 3)) & 0x1F));
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x06, (mode->VTotal - 2) & 0xFF);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x07,
(((mode->VTotal -2) & 0x100) >> 8 )
| (((mode->VDisplay -1) & 0x100) >> 7 )
| ((mode->VSyncStart & 0x100) >> 6 )
| (((mode->VSyncStart) & 0x100) >> 5 )
| 0x10
| (((mode->VTotal -2) & 0x200) >> 4 )
| (((mode->VDisplay -1) & 0x200) >> 3 )
| ((mode->VSyncStart & 0x200) >> 2 ));
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x08, 0x00);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x09, ((mode->VSyncStart & 0x200) >>4) | 0x40);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0A, 0x00);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0B, 0x00);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0C, 0x00);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0D, 0x00);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0E, 0x00);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0F, 0x00);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x10, mode->VSyncStart & 0xFF);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x11, (mode->VSyncEnd & 0x0F) | 0x20);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x12, (mode->VDisplay -1) & 0xFF);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x13, 0x00); /* no interlace */
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x14, 0x00);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x15, mode->VSyncStart & 0xFF);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x16, (mode->VSyncStart +1) & 0xFF);
temp = 0xAF;
if(VDiv2)
temp |= 0x04;
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x17, temp);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x18, 0xFF);
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x1A ,
(((mode->HTotal >> 3) & 0xC0 ) >> 2)
| (((mode->VTotal - 2) & 0x300 ) >> 2));
width = fb_fix.line_length >> 3;
if (fb_var.bits_per_pixel == 1)
width <<= 2;
if(width >= 0xFF)
printk("FB_CIRRUS: Warning line size over the limit ... reduce bpp or width resolution");
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x13, width);
/* Offset extension (see CR13) */
temp = fb_cirrus_read_crt_reg( cirrus_board_ptr, 0x1B);
temp &= 0xAF;
temp |= (width >> (3+4)) & 0x10;
temp |= (width >> (3+3)) & 0x40;
temp |= 0x22;
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x1B, temp);
/****************************************************
* Sequential register
* Enable linear mode and high-res packed pixel mode
*/
temp = fb_cirrus_read_seq_reg( cirrus_board_ptr, 0x07);
temp &= 0xe0;
switch (depthcode) {
case 1:
case 4:
temp |= 0x10;
break;
case 8:
temp |= 0x11;
break;
case 64+8:
temp |= 0x17;
break;
case 15:
temp |= 0x17;
hdr = 0xC0; /* 5:5:5 Sierra */
break;
case 16:
temp |= 0x17;
hdr = 0xC1; /* 5:6:5 XGA mode */
break;
case 24:
temp |= 0x15;
hdr = 0xC5; /* 8:8:8 16M colors */
break;
case 32:
temp |= 0x19;
hdr = 0xC5; /* 8:8:8 16M colors */
break;
default:
printk("FB_CIRRUS: Cannot Initialize display to requested mode\n");
printk("FB_CIRRUS: returning RTEMS_UNSATISFIED on depthcode %d\n", depthcode);
return RTEMS_UNSATISFIED;
}
fb_cirrus_write_seq_reg( cirrus_board_ptr, 0x07, temp);
/* this just set packed pixel mode with according bpp */
/****************************************************
* HDR Register
*/
if(hdr > 0)
fb_cirrus_write_hdr_reg( cirrus_board_ptr, hdr);
/****************************************************
* Graphic Data Controller Registers
*/
temp = fb_cirrus_read_gdc_reg( cirrus_board_ptr, 0x12);
if (HDiv2)
temp |= 0x20;
else
temp &= ~0x20;
fb_cirrus_write_gdc_reg( cirrus_board_ptr, 0x12, temp);
/* Enable high-color modes */
fb_cirrus_write_gdc_reg(cirrus_board_ptr, 0x05, 0x40);
/* VGA graphics mode */
fb_cirrus_write_gdc_reg(cirrus_board_ptr, 0x06, 0x01);
return TRUE;
}
static void
cirrus_prepare_mode( void )
{
active_mode = &available_modes[CIRRUS_DISPLAY_MODE];
fb_var.bits_per_pixel = CIRRUS_DEFAULT_BPP;
fb_var.xres = active_mode->HDisplay;
fb_var.yres = active_mode->VDisplay;
fb_fix.line_length = (fb_var.xres * fb_var.bits_per_pixel + 7) / 8;
fb_fix.type = FB_TYPE_PACKED_PIXELS;
fb_fix.visual = FB_VISUAL_TRUECOLOR;
}
/*
* fb_cirrus device driver OPEN entry point
*/
rtems_device_driver
frame_buffer_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
int r;
uint32_t smem_start, regs_start;
if (_Atomic_Flag_test_and_set(&driver_mutex, ATOMIC_ORDER_ACQUIRE) != 0 ) {
printk( "FB_CIRRUS could not lock driver_mutex\n" );
return RTEMS_UNSATISFIED;
}
r = cirrus_pci_read(&cirrus_board_info, &smem_start, &regs_start);
if ( r == RTEMS_UNSATISFIED )
return RTEMS_UNSATISFIED;
fb_fix.smem_start = (volatile char *)smem_start;
fb_fix.smem_len = 0x1000000;
cirrus_board_info.reg_base = (void *)regs_start;
cirrus_prepare_mode();
cirrus_set_mode( active_mode );
cirrus_adjust_frame( &cirrus_board_info, 0, 0);
if (1) {
uint32_t pixmask;
int x, y;
if(fb_var.bits_per_pixel == 32)
pixmask = 0xffffff;
else
pixmask = (1 << fb_var.bits_per_pixel) - 1;
printk("FB_CIRRUS: mode set, test patter output\n");
for(y = 0; y < fb_var.yres; y++) {
for(x = 0; x < fb_var.xres; x++) {
uint32_t color;
char *addr = (char *)fb_fix.smem_start;
addr += y * fb_fix.line_length;
addr += x * fb_var.bits_per_pixel / 8;
color = x & 1 ? 0 : y & 1 ? pixmask & 0x000ff00f : pixmask;
if(y == fb_var.yres - 1) {
if((x > 0) && (x < fb_var.xres-1))
color = pixmask & 0x00555555;
}
switch (fb_var.bits_per_pixel) {
case 8: *(volatile uint8_t*) addr = color;
break;
case 16: *(volatile uint16_t*) addr = color;
break;
case 24: *(volatile uint32_t*) addr =
(*(volatile uint32_t*) addr & 0xff000000) | color;
break;
case 32: *(volatile uint32_t*) addr = color;
break;
}
}
}
}
return RTEMS_SUCCESSFUL;
}
/*
* fb_cirrus device driver CLOSE entry point
*/
rtems_device_driver
frame_buffer_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
_Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE);
/* restore previous state. for VGA this means return to text mode.
* leave out if graphics hardware has been initialized in
* frame_buffer_initialize() */
/* VGA text mode */
fb_cirrus_write_gdc_reg(&cirrus_board_info, 0x06, 0x00);
printk( "FB_CIRRUS: close called.\n" );
return RTEMS_SUCCESSFUL;
}
/*
* fb_cirrus device driver READ entry point.
*/
rtems_device_driver
frame_buffer_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
memcpy(rw_args->buffer, (const void *) (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved);
return RTEMS_SUCCESSFUL;
}
/*
* frame_buffer device driver WRITE entry point.
*/
rtems_device_driver
frame_buffer_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
memcpy( (void *) (fb_fix.smem_start + rw_args->offset), rw_args->buffer, rw_args->bytes_moved);
return RTEMS_SUCCESSFUL;
}
static int
get_fix_screen_info( struct fb_fix_screeninfo *info )
{
*info = fb_fix;
return 0;
}
static int
get_var_screen_info( struct fb_var_screeninfo *info )
{
*info = fb_var;
return 0;
}
/*
* IOCTL entry point -- This method is called to carry
* all services of this interface.
*/
rtems_device_driver
frame_buffer_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_ioctl_args_t *args = arg;
printk( "FB_CIRRUS ioctl called, cmd=%x\n", args->command );
switch( args->command ) {
case FBIOGET_FSCREENINFO:
args->ioctl_return = get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer );
break;
case FBIOGET_VSCREENINFO:
args->ioctl_return = get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer );
break;
case FBIOPUT_VSCREENINFO:
/* not implemented yet */
args->ioctl_return = -1;
return RTEMS_UNSATISFIED;
case FBIOGETCMAP:
/* no palette - truecolor mode */
args->ioctl_return = -1;
return RTEMS_UNSATISFIED;
case FBIOPUTCMAP:
/* no palette - truecolor mode */
args->ioctl_return = -1;
return RTEMS_UNSATISFIED;
default:
args->ioctl_return = 0;
break;
}
return RTEMS_SUCCESSFUL;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,245 +0,0 @@
/*
* Copyright (c) 2000 - Rosimildo da Silva ( rdasilva@connecttel.com )
*
* MODULE DESCRIPTION:
* This module implements FB driver for "Bare VGA". It uses the
* routines for "bare hardware" found in vgainit.c.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <pthread.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <rtems/libio.h>
#include <rtems/fb.h>
#include <rtems/framebuffer.h>
#include <rtems/score/atomic.h>
/* these routines are defined in vgainit.c.*/
extern void ega_hwinit( void );
extern void ega_hwterm( void );
/* flag to limit driver to protect against multiple opens */
static Atomic_Flag driver_mutex;
/* screen information for the VGA driver */
static struct fb_var_screeninfo fb_var =
{
.xres = 640,
.yres = 480,
.bits_per_pixel = 4
};
static struct fb_fix_screeninfo fb_fix =
{
.smem_start = (volatile char *)0xA0000, /* buffer pointer */
.smem_len = 0x10000, /* buffer size */
.type = FB_TYPE_VGA_PLANES, /* type of dsplay */
.visual = FB_VISUAL_PSEUDOCOLOR, /* color scheme used */
.line_length = 80 /* chars per line */
};
static uint16_t red16[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa,
0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff
};
static uint16_t green16[] = {
0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa,
0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff
};
static uint16_t blue16[] = {
0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa,
0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff
};
/* Functionality to support multiple VGA frame buffers can be added easily,
* but is not supported at this moment because there is no need for two or
* more "classic" VGA adapters. Multiple frame buffer drivers may be
* implemented and If we had implement it they would be named as "/dev/fb0",
* "/dev/fb1", "/dev/fb2" and so on.
*/
/*
* fbvga device driver INITIALIZE entry point.
*/
rtems_device_driver frame_buffer_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code status;
printk( "FBVGA -- driver initializing..\n" );
/*
* Register the device
*/
status = rtems_io_register_name (FRAMEBUFFER_DEVICE_0_NAME, major, 0);
if (status != RTEMS_SUCCESSFUL) {
printk("Error registering " FRAMEBUFFER_DEVICE_0_NAME
" FBVGA framebuffer device!\n");
rtems_fatal_error_occurred( status );
}
_Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE);
return RTEMS_SUCCESSFUL;
}
/*
* fbvga device driver OPEN entry point
*/
rtems_device_driver frame_buffer_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
if (_Atomic_Flag_test_and_set(&driver_mutex, ATOMIC_ORDER_ACQUIRE) != 0 ) {
/* restore previous state. for VGA this means return to text mode.
* leave out if graphics hardware has been initialized in
* frame_buffer_initialize()
*/
ega_hwinit();
printk( "FBVGA open called.\n" );
return RTEMS_SUCCESSFUL;
}
return RTEMS_UNSATISFIED;
}
/*
* fbvga device driver CLOSE entry point
*/
rtems_device_driver frame_buffer_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
_Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE);
/* restore previous state. for VGA this means return to text mode.
* leave out if graphics hardware has been initialized in
* frame_buffer_initialize() */
ega_hwterm();
printk( "FBVGA close called.\n" );
return RTEMS_SUCCESSFUL;
/*
* fbvga device driver READ entry point.
*/
rtems_device_driver frame_buffer_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
memcpy(rw_args->buffer, (const void *) (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved);
return RTEMS_SUCCESSFUL;
}
/*
* frame_buffer device driver WRITE entry point.
*/
rtems_device_driver frame_buffer_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
memcpy( (void *) (fb_fix.smem_start + rw_args->offset), rw_args->buffer, rw_args->bytes_moved);
return RTEMS_SUCCESSFUL;
}
static int get_fix_screen_info( struct fb_fix_screeninfo *info )
{
*info = fb_fix;
return 0;
}
static int get_var_screen_info( struct fb_var_screeninfo *info )
{
*info = fb_var;
return 0;
}
static int get_palette( struct fb_cmap *cmap )
{
uint32_t i;
if ( cmap->start + cmap->len >= 16 )
return 1;
for( i = 0; i < cmap->len; i++ ) {
cmap->red[ cmap->start + i ] = red16[ cmap->start + i ];
cmap->green[ cmap->start + i ] = green16[ cmap->start + i ];
cmap->blue[ cmap->start + i ] = blue16[ cmap->start + i ];
}
return 0;
}
static int set_palette( struct fb_cmap *cmap )
{
uint32_t i;
if ( cmap->start + cmap->len >= 16 )
return 1;
for( i = 0; i < cmap->len; i++ ) {
red16[ cmap->start + i ] = cmap->red[ cmap->start + i ];
green16[ cmap->start + i ] = cmap->green[ cmap->start + i ];
blue16[ cmap->start + i ] = cmap->blue[ cmap->start + i ];
}
return 0;
}
/*
* IOCTL entry point -- This method is called to carry
* all services of this interface.
*/
rtems_device_driver frame_buffer_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_ioctl_args_t *args = arg;
printk( "FBVGA ioctl called, cmd=%x\n", args->command );
switch( args->command ) {
case FBIOGET_FSCREENINFO:
args->ioctl_return = get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer );
break;
case FBIOGET_VSCREENINFO:
args->ioctl_return = get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer );
break;
case FBIOPUT_VSCREENINFO:
/* not implemented yet*/
args->ioctl_return = -1;
return RTEMS_UNSATISFIED;
case FBIOGETCMAP:
args->ioctl_return = get_palette( ( struct fb_cmap * ) args->buffer );
break;
case FBIOPUTCMAP:
args->ioctl_return = set_palette( ( struct fb_cmap * ) args->buffer );
break;
default:
args->ioctl_return = 0;
break;
}
return RTEMS_SUCCESSFUL;
}

View File

@@ -1,170 +0,0 @@
/**
* @file
*
* @ingroup GDB
*
* @brief pc386 gdb select
*
* This file contains a routine to enable and select the UART the gdb stub
* connects too. Currently limited to COM1 and COM2. See
* shared/comm/i386-stub-glue.c file.
*/
/*
* COPYRIGHT (c) 2016.
* Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <stdlib.h>
#include <limits.h>
#include <bsp.h>
#include <rtems/libio.h>
#include <rtems/console.h>
#include <rtems/termiostypes.h>
#include <libchip/serial.h>
#include <libchip/ns16550.h>
#include <bsp/bspimpl.h>
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
/*
* Used in the stub to print output.
*/
int remote_debug;
/*
* Defined in the stub, used here.
*/
void set_debug_traps(void);
/*
* Added here to get a valid baudrate. Needs to go once we
* move to the standard UART driver.
*/
int BSPBaseBaud;
static bool gdb_port_probe(int minor)
{
/* Return false as GDB has claimed the port */
return false;
}
void pc386_parse_gdb_arguments(void)
{
static const char *opt;
/*
* Check the command line to see if com1-com4 are disabled.
*/
opt = bsp_cmdline_arg("--gdb=");
if ( opt ) {
const char *option;
const char *comma;
size_t length;
size_t index;
rtems_device_minor_number minor;
uint32_t baudrate = 115200;
bool halt = false;
console_tbl *port;
/*
* Fine the length, there can be more command line visible.
*/
length = 0;
while ((opt[length] != ' ') && (opt[length] != '\0')) {
++length;
if (length > NAME_MAX) {
printk("invalid option (--gdb): too long\n");
return;
}
}
/*
* Only match up to a comma or NULL
*/
index = 0;
while ((opt[index] != '=') && (index < length)) {
++index;
}
if (opt[index] != '=') {
printk("invalid option (--gdb): no equals\n");
return;
}
++index;
option = &opt[index];
while ((opt[index] != ',') && (index < length)) {
++index;
}
if (opt[index] == ',')
comma = &opt[index];
else
comma = NULL;
length = &opt[index] - option;
port = console_find_console_entry( option, length, &minor );
if ( port == NULL ) {
printk("invalid option (--gdb): port not found\n");
return;
}
if (comma) {
option = comma + 1;
baudrate = strtoul(option, 0, 10);
switch (baudrate) {
case 115200:
case 57600:
case 38400:
case 19200:
case 9600:
case 4800:
port->pDeviceParams = (void*) baudrate;
BSPBaseBaud = baudrate; /* REMOVE ME */
break;
default:
printk("invalid option (--gdb): bad baudrate\n");
return;
}
}
/*
* Provide a probe that fails so the device is not part of termios. All
* functions are polling.
*/
port->deviceProbe = gdb_port_probe;
port->pDeviceFns = &ns16550_fns_polled;
opt = bsp_cmdline_arg("--gdb-remote-debug");
if ( opt ) {
remote_debug = 1;
}
opt = bsp_cmdline_arg("--gdb-break");
if ( opt ) {
halt = true;
}
printk("GDB stub: enable %s%s%s\n",
port->sDeviceName,
remote_debug ? ", remote-debug" : "",
halt ? ", halting" : "");
i386_stub_glue_init(minor);
set_debug_traps();
i386_stub_glue_init_breakin();
if ( halt ) {
printk("GDB stub: waiting for remote connection..\n");
breakpoint();
}
}
}

View File

@@ -1,192 +0,0 @@
/**
* @file
*
* @ingroup i386_pc386
*
* @brief I386 keyboard definitions.
*/
/*
* linux/include/asm-i386/keyboard.h
*
* Created 3 Nov 1996 by Geert Uytterhoeven
*/
/*
* This file contains the i386 architecture specific keyboard definitions
*/
#ifndef _I386_KEYBOARD_H
#define _I386_KEYBOARD_H
#include <i386_io.h>
#define KEYBOARD_IRQ 1
#define DISABLE_KBD_DURING_INTERRUPTS 0
extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
extern int pckbd_getkeycode(unsigned int scancode);
extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
char raw_mode);
extern char pckbd_unexpected_up(unsigned char keycode);
extern void pckbd_leds(unsigned char leds);
extern void pckbd_init_hw(void);
extern unsigned char pckbd_sysrq_xlate[128];
#define kbd_setkeycode pckbd_setkeycode
#define kbd_getkeycode pckbd_getkeycode
#define kbd_translate pckbd_translate
#define kbd_unexpected_up pckbd_unexpected_up
#define kbd_leds pckbd_leds
#define kbd_init_hw pckbd_init_hw
#define kbd_sysrq_xlate pckbd_sysrq_xlate
#define SYSRQ_KEY 0x54
/* resource allocation */
#define kbd_request_region() /* request_region(0x60, 16, "keyboard") */
#define kbd_request_irq(handler) /* request_irq(KEYBOARD_IRQ, handler, 0, "keyboard", NULL) */
/* How to access the keyboard macros on this platform. */
#define kbd_read_input() inb(KBD_DATA_REG)
#define kbd_read_status() inb(KBD_STATUS_REG)
#define kbd_write_output(val) outb(val, KBD_DATA_REG)
#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
/* Some stoneage hardware needs delays after some operations. */
#define kbd_pause() do { } while(0)
/*
* Machine specific bits for the PS/2 driver
*/
#define AUX_IRQ 12
#define aux_request_irq(hand, dev_id) /* request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id) */
#define aux_free_irq(dev_id) /* free_irq(AUX_IRQ, dev_id) */
/*
* include/linux/pc_keyb.h
*
* PC Keyboard And Keyboard Controller
*
* (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*/
/*
* Configuration Switches
*/
#undef KBD_REPORT_ERR /* Report keyboard errors */
#define KBD_REPORT_UNKN /* Report unknown scan codes */
#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */
#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */
#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */
#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */
/*
* Internal variables of the driver
*/
extern unsigned char pckbd_read_mask;
extern unsigned char aux_device_present;
/*
* Keyboard Controller Registers on normal PCs.
*/
#define KBD_STATUS_REG 0x64 /* Status register (R) */
#define KBD_CNTL_REG 0x64 /* Controller command register (W) */
#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */
/*
* Keyboard Controller Commands
*/
#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
initiated by the auxiliary device */
#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
/*
* Keyboard Commands
*/
#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
#define KBD_CMD_RESET 0xFF /* Reset */
/*
* Keyboard Replies
*/
#define KBD_REPLY_POR 0xAA /* Power on reset */
#define KBD_REPLY_ACK 0xFA /* Command ACK */
#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
/*
* Status Register Bits
*/
#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
#define KBD_STAT_PERR 0x80 /* Parity error */
#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
/*
* Controller Mode Register Bits
*/
#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
#define KBD_MODE_SYS 0x04 /* The system flag (?) */
#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
#define KBD_MODE_RFU 0x80
/*
* Mouse Commands
*/
#define AUX_SET_RES 0xE8 /* Set resolution */
#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
#define AUX_SET_STREAM 0xEA /* Set stream mode */
#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
#define AUX_RESET 0xFF /* Reset aux device */
#define AUX_ACK 0xFA /* Command byte ACK. */
#define AUX_BUF_SIZE 2048 /* This might be better divisible by
three to make overruns stay in sync
but then the read function would need
a lock etc - ick */
#define mark_bh(x)
#endif /* _I386_KEYBOARD_H */

View File

@@ -1,300 +0,0 @@
/*-------------------------------------------------------------------------+
| inch.c v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is based on:
| inch.c,v 1.3 1995/12/19 20:07:25 joel Exp - go32 BSP
| With the following copyright notice:
| With the following copyright notice:
| **************************************************************************
| * COPYRIGHT (c) 1989-1998.
| * On-Line Applications Research Corporation (OAR).
| *
| * The license and distribution terms for this file may be
| * found in the file LICENSE in this distribution or at
| * http://www.rtems.org/license/LICENSE.
| **************************************************************************
+--------------------------------------------------------------------------*/
#include <bsp.h>
#include <bsp/bootcard.h>
#include <bsp/irq.h>
/*-------------------------------------------------------------------------+
| Constants
+--------------------------------------------------------------------------*/
#define KBD_CTL 0x61 /* -------------------------------- */
#define KBD_DATA 0x60 /* Ports for PC keyboard controller */
#define KBD_STATUS 0x64 /* -------------------------------- */
#define KBD_BUF_SIZE 256
/*-------------------------------------------------------------------------+
| Global Variables
+--------------------------------------------------------------------------*/
static char key_map[] =
{
0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t',
'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80,
'a','s','d','f','g','h','j','k','l',';',047,0140,0x80,
0134,'z','x','c','v','b','n','m',',','.','/',0x80,
'*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,'0',0177
}; /* Keyboard scancode -> character map with no modifiers. */
static char shift_map[] =
{
0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t',
'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80,
'A','S','D','F','G','H','J','K','L',':',042,'~',0x80,
'|','Z','X','C','V','B','N','M','<','>','?',0x80,
'*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80,
'1','2','3','0',177
}; /* Keyboard scancode -> character map with SHIFT key modifier. */
static unsigned short kbd_buffer[KBD_BUF_SIZE];
static uint16_t kbd_first = 0;
static uint16_t kbd_last = 0;
static uint16_t kbd_end = KBD_BUF_SIZE - 1;
/*-------------------------------------------------------------------------+
| Function: _IBMPC_scankey
| Description: This function can be called during a poll for input, or by
| an ISR. Basically any time you want to process a keypress.
| Global Variables: key_map, shift_map.
| Arguments: outChar - character read in case of a valid reading,
| otherwise unchanged.
| Returns: TRUE in case a valid character has been read,
| FALSE otherwise.
+--------------------------------------------------------------------------*/
static bool
_IBMPC_scankey(char *outChar)
{
unsigned char inChar;
static int alt_pressed = 0;
static int ctrl_pressed = 0;
static int shift_pressed = 0;
static int caps_pressed = 0;
static int extended = 0;
*outChar = '\0'; /* default value if we return false */
/* Read keyboard controller, toggle enable */
inport_byte(KBD_CTL, inChar);
outport_byte(KBD_CTL, inChar & ~0x80);
outport_byte(KBD_CTL, inChar | 0x80);
outport_byte(KBD_CTL, inChar & ~0x80);
/* See if it has data */
inport_byte(KBD_STATUS, inChar);
if ((inChar & 0x01) == 0)
return false;
/* Read the data. Handle nonsense with shift, control, etc. */
inport_byte(KBD_DATA, inChar);
if (extended)
extended--;
switch (inChar)
{
case 0xe0:
extended = 2;
return false;
break;
case 0x38:
alt_pressed = 1;
return false;
break;
case 0xb8:
alt_pressed = 0;
return false;
break;
case 0x1d:
ctrl_pressed = 1;
return false;
break;
case 0x9d:
ctrl_pressed = 0;
return false;
break;
case 0x2a:
if (extended)
return false;
case 0x36:
shift_pressed = 1;
return false;
break;
case 0xaa:
if (extended)
return false;
case 0xb6:
shift_pressed = 0;
return false;
break;
case 0x3a:
caps_pressed = 1;
return false;
break;
case 0xba:
caps_pressed = 0;
return false;
break;
case 0x53:
if (ctrl_pressed && alt_pressed)
bsp_reset(); /* ctrl+alt+del -> reboot */
break;
/*
* Ignore unrecognized keys--usually arrow and such
*/
default:
if ((inChar & 0x80) || (inChar > 0x39))
/* High-bit on means key is being released, not pressed */
return false;
break;
} /* switch */
/* Strip high bit, look up in our map */
inChar &= 0x7f;
if (ctrl_pressed)
{
*outChar = key_map[inChar];
*outChar &= 037;
}
else
{
*outChar = shift_pressed ? shift_map[inChar] : key_map[inChar];
if (caps_pressed)
{
if (*outChar >= 'A' && *outChar <= 'Z')
*outChar += 'a' - 'A';
else if (*outChar >= 'a' && *outChar <= 'z')
*outChar -= 'a' - 'A';
}
}
return true;
} /* _IBMPC_scankey */
/*-------------------------------------------------------------------------+
| Function: _IBMPC_chrdy
| Description: Check keyboard ISR buffer and return character if not empty.
| Global Variables: kbd_buffer, kbd_first, kbd_last.
| Arguments: c - character read if keyboard buffer not empty, otherwise
| unchanged.
| Returns: TRUE if keyboard buffer not empty, FALSE otherwise.
+--------------------------------------------------------------------------*/
static bool
_IBMPC_chrdy(char *c)
{
#if CCJ_REMOVED_NO_IDEA_ABOUT_THIS_CODE_OR_COMMENT
/* FIX ME!!! It doesn't work without something like the following line.
Find out why! */
printk("");
#endif
/* Check buffer our ISR builds */
if (kbd_first != kbd_last)
{
*c = kbd_buffer[kbd_first];
kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
return true;
}
else
return false;
} /* _IBMPC_chrdy */
/*-------------------------------------------------------------------------+
| Function: _IBMPC_inch
| Description: Poll keyboard until a character is ready and return it.
| Global Variables: None.
| Arguments: None.
| Returns: character read from keyboard.
+--------------------------------------------------------------------------*/
char
_IBMPC_inch(void)
{
char c;
while (!_IBMPC_chrdy(&c))
continue;
return c;
} /* _IBMPC_inch */
/*
* Routine that can be used before interrupt management is initialized.
*/
int BSP_wait_polled_input(void)
{
char c;
while (!_IBMPC_scankey(&c))
continue;
return c;
}
/*
* Check if a key has been pressed. This is a non-destructive
* call, meaning, it keeps the key in the buffer.
*/
int rtems_kbpoll( void )
{
int rc;
/*
* The locking or disable of interrupts does not help
* there because if interrupts are enabled after leave of this
* function the state can change without notice anyway.
*/
RTEMS_COMPILER_MEMORY_BARRIER();
rc = ( kbd_first != kbd_last ) ? TRUE : FALSE;
RTEMS_COMPILER_MEMORY_BARRIER();
return rc;
}
int getch( void )
{
int c;
while( kbd_first == kbd_last )
{
rtems_task_wake_after( 10 );
}
c = kbd_buffer[ kbd_first ];
kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
return c;
}
void add_to_queue( unsigned short b )
{
unsigned int next;
kbd_buffer[ kbd_last ] = b;
next = (kbd_last == kbd_end) ? 0 : kbd_last + 1;
if( next != kbd_first )
{
kbd_last = next;
}
}

View File

@@ -1,47 +0,0 @@
/*
* The contents of this file were formerly in console.c which
* had the following copyright notice:
*
* (C) Copyright 1997
* NavIST Group - Real-Time Distributed Systems and Industrial Automation
* http://pandora.ist.utl.pt
* Instituto Superior Tecnico * Lisboa * PORTUGAL
*
* The original code and subsequent modifications are:
*
* COPYRIGHT (c) 1989-2011.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems.h>
#include <rtems/keyboard.h>
#include <rtems/mw_uid.h>
/* adds a kbd message to the queue */
static void kbd_parser( void *ptr, unsigned short keycode, unsigned long mods )
{
struct MW_UID_MESSAGE m;
struct kbd_struct * kbd = (struct kbd_struct *)ptr;
m.type = MV_UID_KBD;
m.m.kbd.code = keycode;
m.m.kbd.modifiers = kbd->ledflagstate;
m.m.kbd.mode = kbd->kbdmode;
/* printk( "kbd: msg: keycode=%X, mod=%X\n", keycode, mods ); */
uid_send_message( &m );
}
void register_kbd_msg_queue( char *q_name, int port )
{
kbd_set_driver_handler( kbd_parser );
}
void unregister_kbd_msg_queue( int port )
{
kbd_set_driver_handler( NULL );
}

View File

@@ -1,881 +0,0 @@
/*
* Rosimildo da Silva: rdasilva@connecttel.com
*/
#include <limits.h>
#include <sys/types.h>
#include <rtems/keyboard.h>
#include "i386kbd.h"
#include <rtems/kd.h>
#include <bsp.h>
#include <bsp/bootcard.h>
#include <stdatomic.h>
#define SIZE(x) (sizeof(x)/sizeof((x)[0]))
#ifndef KBD_DEFMODE
#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
#endif
#ifndef KBD_DEFLEDS
/*
* Some laptops take the 789uiojklm,. keys as number pad when NumLock
* is on. This seems a good reason to start with NumLock off.
*/
#define KBD_DEFLEDS 0
#endif
#ifndef KBD_DEFLOCK
#define KBD_DEFLOCK 0
#endif
static int kbd_test_and_set_bit(int nr, atomic_uint_least32_t * addr)
{
uint_least32_t mask;
int retval;
addr += nr >> 5;
mask = 1UL << (nr & 0x1f);
retval = (atomic_fetch_or(addr, mask) & mask) != 0;
return retval;
}
static int kbd_test_and_clear_bit(int nr, atomic_uint_least32_t * addr)
{
uint_least32_t mask;
int retval;
addr += nr >> 5;
mask = 1UL << (nr & 0x1f);
retval = (atomic_fetch_and(addr, ~mask) & mask) != 0;
return retval;
}
static int kbd_test_bit(int nr, atomic_uint_least32_t * addr)
{
unsigned long mask;
addr += nr >> 5;
mask = 1 << (nr & 0x1f);
return ((mask & atomic_load(addr)) != 0);
}
/*
* global state includes the following, and various static variables
* in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next.
* (last_console is now a global variable)
*/
#define KBD_BITS_PER_ELEMENT (sizeof(atomic_uint_least32_t)*CHAR_BIT)
/* shift state counters.. */
static unsigned char k_down[NR_SHIFT] = {0, };
/* keyboard key bitmap */
static atomic_uint_least32_t
key_down[(256 + KBD_BITS_PER_ELEMENT - 1) / KBD_BITS_PER_ELEMENT] = { 0, };
static int dead_key_next = 0;
/*
* In order to retrieve the shift_state (for the mouse server), either
* the variable must be global, or a new procedure must be created to
* return the value. I chose the former way.
*/
int shift_state = 0;
static int npadch = -1; /* -1 or number assembled on pad */
static unsigned char diacr = 0;
static char rep = 0; /* flag telling character repeat */
/* default console for RTEMS */
static int fg_console = 0;
struct kbd_struct kbd_table[MAX_NR_CONSOLES];
static struct kbd_struct * kbd = kbd_table;
void compute_shiftstate(void);
typedef void (*k_hand)(unsigned char value, char up_flag);
typedef void (k_handfn)(unsigned char value, char up_flag);
static k_handfn
do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
do_ignore;
static k_hand key_handler[16] = {
do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
do_ignore, do_ignore
};
/* Key types processed even in raw modes */
#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT))
typedef void (*void_fnp)(void);
typedef void (void_fn)(void);
static void show_mem(void)
{
}
static void show_state(void)
{
}
static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle,
num, hold, scroll_forw, scroll_back, caps_on, compose,
SAK, decr_console, incr_console, spawn_console, bare_num;
static void_fnp spec_fn_table[] = {
do_null, enter, show_ptregs, show_mem,
show_state, send_intr, lastcons, caps_toggle,
num, hold, scroll_forw, scroll_back,
bsp_reset, caps_on, compose, SAK,
decr_console, incr_console, spawn_console, bare_num
};
#define SPECIALS_ALLOWED_IN_RAW_MODE (1 << KVAL(K_SAK))
/* maximum values each key_handler can handle */
const int max_vals[] = {
255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1,
NR_DEAD - 1, 255, 3, NR_SHIFT - 1,
255, NR_ASCII - 1, NR_LOCK - 1, 255,
NR_LOCK - 1, 255
};
const int NR_TYPES = SIZE(max_vals);
/* N.B. drivers/macintosh/mac_keyb.c needs to call put_queue */
static void put_queue(int);
static unsigned char handle_diacr(unsigned char);
#ifdef CONFIG_MAGIC_SYSRQ
static int sysrq_pressed;
#endif
/*
* Many other routines do put_queue, but I think either
* they produce ASCII, or they produce some user-assigned
* string, and in both cases we might assume that it is
* in utf-8 already.
*/
static void to_utf8(ushort c)
{
if (c < 0x80)
put_queue(c); /* 0******* */
else if (c < 0x800) {
put_queue(0xc0 | (c >> 6)); /* 110***** 10****** */
put_queue(0x80 | (c & 0x3f));
} else {
put_queue(0xe0 | (c >> 12)); /* 1110**** 10****** 10****** */
put_queue(0x80 | ((c >> 6) & 0x3f));
put_queue(0x80 | (c & 0x3f));
}
/* UTF-8 is defined for words of up to 31 bits,
but we need only 16 bits here */
}
/*
* Translation of escaped scancodes to keycodes.
* This is now user-settable (for machines were it makes sense).
*/
int setkeycode(unsigned int scancode, unsigned int keycode)
{
return kbd_setkeycode(scancode, keycode);
}
int getkeycode(unsigned int scancode)
{
return kbd_getkeycode(scancode);
}
void handle_scancode(unsigned char scancode, int down)
{
unsigned char keycode;
char up_flag = down ? 0 : 0200;
char raw_mode;
mark_bh(CONSOLE_BH);
#if 0
tty = ttytab? ttytab[fg_console]: NULL;
if (tty && (!tty->driver_data)) {
/*
* We touch the tty structure via the the ttytab array
* without knowing whether or not tty is open, which
* is inherently dangerous. We currently rely on that
* fact that console_open sets tty->driver_data when
* it opens it, and clears it when it closes it.
*/
tty = NULL;
}
#endif
kbd = kbd_table + fg_console;
if ((raw_mode = (kbd->kbdmode == VC_RAW))) {
put_queue(scancode | up_flag);
/* we do not return yet, because we want to maintain
the key_down array, so that we have the correct
values when finishing RAW mode or when changing VT's */
}
/*
* Convert scancode to keycode
*/
if (!kbd_translate(scancode, &keycode, raw_mode))
return;
/*
* At this point the variable `keycode' contains the keycode.
* Note: the keycode must not be 0 (++Geert: on m68k 0 is valid).
* We keep track of the up/down status of the key, and
* return the keycode if in MEDIUMRAW mode.
*/
if (up_flag) {
rep = 0;
if(!kbd_test_and_clear_bit(keycode, key_down))
up_flag = kbd_unexpected_up(keycode);
} else
rep = kbd_test_and_set_bit(keycode, key_down);
#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
if (keycode == SYSRQ_KEY) {
sysrq_pressed = !up_flag;
return;
} else if (sysrq_pressed) {
if (!up_flag && sysrq_enabled)
handle_sysrq(kbd_sysrq_xlate[keycode], kbd_pt_regs, kbd, tty);
return;
}
#endif
if (kbd->kbdmode == VC_MEDIUMRAW) {
/* soon keycodes will require more than one byte */
put_queue(keycode + up_flag);
raw_mode = 1; /* Most key classes will be ignored */
}
/*
* Small change in philosophy: earlier we defined repetition by
* rep = keycode == prev_keycode;
* prev_keycode = keycode;
* but now by the fact that the depressed key was down already.
* Does this ever make a difference? Yes.
*/
/*
* Repeat a key only if the input buffers are empty or the
* characters get echoed locally. This makes key repeat usable
* with slow applications and under heavy loads.
*/
if (!rep || vc_kbd_mode(kbd,VC_REPEAT) ) {
/*
|| (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
(L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) {
*/
u_short keysym;
u_char type;
/* the XOR below used to be an OR */
int shift_final = shift_state ^ kbd->lockstate ^ kbd->slockstate;
ushort *key_map = key_maps[shift_final];
if (key_map != NULL) {
keysym = key_map[keycode];
type = KTYP(keysym);
if (type >= 0xf0) {
type -= 0xf0;
if (raw_mode && ! (TYPES_ALLOWED_IN_RAW_MODE & (1 << type)))
return;
if (type == KT_LETTER) {
type = KT_LATIN;
if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
if (key_map)
keysym = key_map[keycode];
}
}
(*key_handler[type])(keysym & 0xff, up_flag);
if (type != KT_SLOCK)
kbd->slockstate = 0;
} else {
/* maybe only if (kbd->kbdmode == VC_UNICODE) ? */
if (!up_flag && !raw_mode)
to_utf8(keysym);
}
} else {
/* maybe beep? */
/* we have at least to update shift_state */
#if 1 /* how? two almost equivalent choices follow */
compute_shiftstate();
#else
keysym = U(plain_map[keycode]);
type = KTYP(keysym);
if (type == KT_SHIFT)
(*key_handler[type])(keysym & 0xff, up_flag);
#endif
}
}
}
static void ( *driver_input_handler_kbd )( void *, unsigned short, unsigned long ) = 0;
/*
*/
void kbd_set_driver_handler(
void ( *handler )( void *, unsigned short, unsigned long )
)
{
driver_input_handler_kbd = handler;
}
static void put_queue(int ch)
{
if ( driver_input_handler_kbd ) {
driver_input_handler_kbd( ( void *)kbd, (unsigned short)ch, 0 );
} else {
add_to_queue( ch );
}
}
static void puts_queue(char *cp)
{
while (*cp) {
put_queue( *cp );
cp++;
}
}
static void applkey(int key, char mode)
{
static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
buf[1] = (mode ? 'O' : '[');
buf[2] = key;
puts_queue(buf);
}
static void enter(void)
{
if (diacr) {
put_queue(diacr);
diacr = 0;
}
put_queue(13);
if (vc_kbd_mode(kbd,VC_CRLF))
put_queue(10);
}
static void caps_toggle(void)
{
if (rep)
return;
chg_vc_kbd_led(kbd, VC_CAPSLOCK);
}
static void caps_on(void)
{
if (rep)
return;
set_vc_kbd_led(kbd, VC_CAPSLOCK);
}
static void show_ptregs(void)
{
}
static void hold(void)
{
if (rep )
return;
chg_vc_kbd_led(kbd, VC_SCROLLOCK );
}
static void num(void)
{
if (vc_kbd_mode(kbd,VC_APPLIC))
applkey('P', 1);
else
bare_num();
}
/*
* Bind this to Shift-NumLock if you work in application keypad mode
* but want to be able to change the NumLock flag.
* Bind this to NumLock if you prefer that the NumLock key always
* changes the NumLock flag.
*/
static void bare_num(void)
{
if (!rep)
chg_vc_kbd_led(kbd,VC_NUMLOCK);
}
static void lastcons(void)
{
}
static void decr_console(void)
{
}
static void incr_console(void)
{
}
static void send_intr(void)
{
}
static void scroll_forw(void)
{
}
static void scroll_back(void)
{
}
static void compose(void)
{
dead_key_next = 1;
}
int spawnpid, spawnsig;
static void spawn_console(void)
{
}
static void SAK(void)
{
}
static void do_ignore(unsigned char value, char up_flag)
{
}
static void do_null()
{
compute_shiftstate();
}
static void do_spec(unsigned char value, char up_flag)
{
if (up_flag)
return;
if (value >= SIZE(spec_fn_table))
return;
if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) &&
!(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value)))
return;
spec_fn_table[value]();
}
static void do_lowercase(unsigned char value, char up_flag)
{
}
static void do_self(unsigned char value, char up_flag)
{
if (up_flag)
return; /* no action, if this is a key release */
if (diacr)
value = handle_diacr(value);
if (dead_key_next) {
dead_key_next = 0;
diacr = value;
return;
}
put_queue(value);
}
#define A_GRAVE '`'
#define A_ACUTE '\''
#define A_CFLEX '^'
#define A_TILDE '~'
#define A_DIAER '"'
#define A_CEDIL ','
static unsigned char ret_diacr[NR_DEAD] =
{A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL };
/* Obsolete - for backwards compatibility only */
static void do_dead(unsigned char value, char up_flag)
{
value = ret_diacr[value];
printk( " do_dead( %X ) ", value );
do_dead2(value,up_flag);
}
/*
* Handle dead key. Note that we now may have several
* dead keys modifying the same character. Very useful
* for Vietnamese.
*/
static void do_dead2(unsigned char value, char up_flag)
{
if (up_flag)
return;
diacr = (diacr ? handle_diacr(value) : value);
}
/*
* We have a combining character DIACR here, followed by the character CH.
* If the combination occurs in the table, return the corresponding value.
* Otherwise, if CH is a space or equals DIACR, return DIACR.
* Otherwise, conclude that DIACR was not combining after all,
* queue it and return CH.
*/
unsigned char handle_diacr(unsigned char ch)
{
int d = diacr;
int i;
diacr = 0;
for (i = 0; i < accent_table_size; i++) {
if (accent_table[i].diacr == d && accent_table[i].base == ch)
return accent_table[i].result;
}
if (ch == ' ' || ch == d)
return d;
put_queue(d);
return ch;
}
static void do_cons(unsigned char value, char up_flag)
{
if (up_flag)
return;
}
static void do_fn(unsigned char value, char up_flag)
{
if (up_flag)
return;
if (value < SIZE(func_table)) {
if (func_table[value])
puts_queue(func_table[value]);
} else
printk( "do_fn called with value=%d\n", value);
}
static void do_pad(unsigned char value, char up_flag)
{
static const char *pad_chars = "0123456789+-*/\015,.?()";
static const char *app_map = "pqrstuvwxylSRQMnnmPQ";
if (up_flag)
return; /* no action, if this is a key release */
/* kludge... shift forces cursor/number keys */
if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
applkey(app_map[value], 1);
return;
}
if (!vc_kbd_led(kbd,VC_NUMLOCK))
switch (value) {
case KVAL(K_PCOMMA):
case KVAL(K_PDOT):
do_fn(KVAL(K_REMOVE), 0);
return;
case KVAL(K_P0):
do_fn(KVAL(K_INSERT), 0);
return;
case KVAL(K_P1):
do_fn(KVAL(K_SELECT), 0);
return;
case KVAL(K_P2):
do_cur(KVAL(K_DOWN), 0);
return;
case KVAL(K_P3):
do_fn(KVAL(K_PGDN), 0);
return;
case KVAL(K_P4):
do_cur(KVAL(K_LEFT), 0);
return;
case KVAL(K_P6):
do_cur(KVAL(K_RIGHT), 0);
return;
case KVAL(K_P7):
do_fn(KVAL(K_FIND), 0);
return;
case KVAL(K_P8):
do_cur(KVAL(K_UP), 0);
return;
case KVAL(K_P9):
do_fn(KVAL(K_PGUP), 0);
return;
case KVAL(K_P5):
applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
return;
}
put_queue(pad_chars[value]);
if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
put_queue(10);
}
static void do_cur(unsigned char value, char up_flag)
{
static const char *cur_chars = "BDCA";
if (up_flag)
return;
applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
}
static void do_shift(unsigned char value, char up_flag)
{
int old_state = shift_state;
if (rep)
return;
/* Mimic typewriter:
a CapsShift key acts like Shift but undoes CapsLock */
if (value == KVAL(K_CAPSSHIFT)) {
value = KVAL(K_SHIFT);
if (!up_flag)
clr_vc_kbd_led(kbd, VC_CAPSLOCK);
}
if (up_flag) {
/* handle the case that two shift or control
keys are depressed simultaneously */
if (k_down[value])
k_down[value]--;
} else
k_down[value]++;
if (k_down[value])
shift_state |= (1 << value);
else
shift_state &= ~ (1 << value);
/* kludge */
if (up_flag && shift_state != old_state && npadch != -1) {
if (kbd->kbdmode == VC_UNICODE)
to_utf8(npadch & 0xffff);
else
put_queue(npadch & 0xff);
npadch = -1;
}
}
/* called after returning from RAW mode or when changing consoles -
recompute k_down[] and shift_state from key_down[] */
/* maybe called when keymap is undefined, so that shiftkey release is seen */
void compute_shiftstate(void)
{
int i, j, k, sym, val;
shift_state = 0;
for(i=0; i < SIZE(k_down); i++)
k_down[i] = 0;
for(i=0; i < SIZE(key_down); i++)
if(atomic_load(key_down + i)) { /* skip this word if not a single bit on */
k = i*KBD_BITS_PER_ELEMENT;
for(j=0; j<KBD_BITS_PER_ELEMENT; j++,k++)
if(kbd_test_bit(k, key_down)) {
sym = U(plain_map[k]);
if(KTYP(sym) == KT_SHIFT) {
val = KVAL(sym);
if (val == KVAL(K_CAPSSHIFT))
val = KVAL(K_SHIFT);
k_down[val]++;
shift_state |= (1<<val);
}
}
}
}
static void do_meta(unsigned char value, char up_flag)
{
if (up_flag)
return;
if (vc_kbd_mode(kbd, VC_META)) {
put_queue('\033');
put_queue(value);
} else
put_queue(value | 0x80);
}
static void do_ascii(unsigned char value, char up_flag)
{
int base;
if (up_flag)
return;
if (value < 10) /* decimal input of code, while Alt depressed */
base = 10;
else { /* hexadecimal input of code, while AltGr depressed */
value -= 10;
base = 16;
}
if (npadch == -1)
npadch = value;
else
npadch = npadch * base + value;
}
static void do_lock(unsigned char value, char up_flag)
{
if (up_flag || rep)
return;
chg_vc_kbd_lock(kbd, value);
}
static void do_slock(unsigned char value, char up_flag)
{
if (up_flag || rep)
return;
chg_vc_kbd_slock(kbd, value);
}
/*
* The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
* or (ii) whatever pattern of lights people want to show using KDSETLED,
* or (iii) specified bits of specified words in kernel memory.
*/
static unsigned char ledstate = 0xff; /* undefined */
static unsigned char ledioctl;
unsigned char getledstate(void) {
return ledstate;
}
void setledstate(struct kbd_struct *kbd, unsigned int led) {
if (!(led & ~7)) {
ledioctl = led;
kbd->ledmode = LED_SHOW_IOCTL;
} else
;
kbd->ledmode = LED_SHOW_FLAGS;
set_leds();
}
static struct ledptr {
unsigned int *addr;
unsigned int mask;
unsigned char valid:1;
} ledptrs[3];
void register_leds(
int console,
unsigned int led,
unsigned int *addr,
unsigned int mask
)
{
struct kbd_struct *kbd = kbd_table + console;
if (led < 3) {
ledptrs[led].addr = addr;
ledptrs[led].mask = mask;
ledptrs[led].valid = 1;
kbd->ledmode = LED_SHOW_MEM;
} else
kbd->ledmode = LED_SHOW_FLAGS;
}
static inline unsigned char getleds(void)
{
struct kbd_struct *kbd = kbd_table + fg_console;
unsigned char leds;
if (kbd->ledmode == LED_SHOW_IOCTL)
return ledioctl;
leds = kbd->ledflagstate;
if (kbd->ledmode == LED_SHOW_MEM) {
if (ledptrs[0].valid) {
if (*ledptrs[0].addr & ledptrs[0].mask)
leds |= 1;
else
leds &= ~1;
}
if (ledptrs[1].valid) {
if (*ledptrs[1].addr & ledptrs[1].mask)
leds |= 2;
else
leds &= ~2;
}
if (ledptrs[2].valid) {
if (*ledptrs[2].addr & ledptrs[2].mask)
leds |= 4;
else
leds &= ~4;
}
}
return leds;
}
/*
* This routine is the bottom half of the keyboard interrupt
* routine, and runs with all interrupts enabled. It does
* console changing, led setting and copy_to_cooked, which can
* take a reasonably long time.
*
* Aside from timing (which isn't really that important for
* keyboard interrupts as they happen often), using the software
* interrupt routines for this thing allows us to easily mask
* this when we don't want any of the above to happen. Not yet
* used, but this allows for easy and efficient race-condition
* prevention later on.
*/
static void kbd_bh(void)
{
unsigned char leds = getleds();
if (leds != ledstate) {
ledstate = leds;
kbd_leds(leds);
}
}
void set_leds(void)
{
kbd_bh();
}
int kbd_init(void)
{
int i;
struct kbd_struct kbd0;
kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
kbd0.ledmode = LED_SHOW_MEM;
kbd0.lockstate = KBD_DEFLOCK;
kbd0.slockstate = 0;
kbd0.modeflags = KBD_DEFMODE;
kbd0.kbdmode = VC_XLATE;
for (i = 0 ; i < MAX_NR_CONSOLES ; i++)
kbd_table[i] = kbd0;
kbd_init_hw();
mark_bh(KEYBOARD_BH);
return 0;
}

View File

@@ -1,328 +0,0 @@
/*
* outch.c - This file contains code for displaying characters
* on the console uisng information that should be
* maintained by the BIOS in its data Area.
*
* Copyright (C) 1998 Eric Valette (valette@crf.canon.fr)
* Canon Centre Recherche France.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Till Straumann <strauman@slac.stanford.edu>, 2003/9:
* - added handling of basic escape sequences (cursor movement
* and erasing; just enough for the line editor 'libtecla' to
* work...)
*/
#include <bsp.h>
#include <stdlib.h>
#include <string.h>
#include <crt.h>
extern void wr_cursor(int, unsigned short);
#define TAB_SPACE 4
static unsigned short *bitMapBaseAddr;
static unsigned short ioCrtBaseAddr;
static unsigned short maxCol;
static unsigned short maxRow;
static unsigned char row;
static unsigned char column;
static unsigned short attribute;
static unsigned int nLines;
static void
scroll(void)
{
int i, j; /* Counters */
unsigned short *pt_scroll, *pt_bitmap; /* Pointers on the bit-map */
pt_bitmap = bitMapBaseAddr;
j = 0;
pt_bitmap = pt_bitmap + j;
pt_scroll = pt_bitmap + maxCol;
for (i = j; i < (maxRow - 1) * maxCol; i++) {
*pt_bitmap++ = *pt_scroll++;
}
/*
* Blank characters are displayed on the last line.
*/
for (i = 0; i < maxCol; i++) {
*pt_bitmap++ = (short) (' ' | attribute);
}
}
static void
doCRNL(int cr, int nl)
{
if (nl) {
if (++row == maxRow) {
scroll(); /* Scroll the screen now */
row = maxRow - 1;
}
nLines++;
}
if (cr)
column = 0;
/* Move cursor on the next location */
if (cr || nl)
wr_cursor(row * maxCol + column, ioCrtBaseAddr);
}
int (*videoHook)(char, int *)=0;
static void
advanceCursor(void)
{
if (++column == maxCol)
doCRNL(1,1);
else
wr_cursor(row * maxCol + column, ioCrtBaseAddr);
}
static void
gotorc(int r, int c)
{
column = c;
row = r;
wr_cursor(row * maxCol + column, ioCrtBaseAddr);
}
#define ESC ((char)27)
/* erase current location without moving the cursor */
#define BLANK ((char)0x7f)
static void
videoPutChar(char car)
{
unsigned short *pt_bitmap = bitMapBaseAddr + row * maxCol + column;
switch (car) {
case '\b': {
if (column) column--;
/* Move cursor on the previous location */
wr_cursor(row * maxCol + column, ioCrtBaseAddr);
return;
}
case '\t': {
int i;
i = TAB_SPACE - (column & (TAB_SPACE - 1));
column += i;
if (column >= maxCol) {
doCRNL(1,1);
return;
}
while (i--) *pt_bitmap++ = ' ' | attribute;
wr_cursor(row * maxCol + column, ioCrtBaseAddr);
return;
}
case '\n': {
doCRNL(0,1);
return;
}
case 7: { /* Bell code must be inserted here */
return;
}
case '\r' : {
doCRNL(1,0);
return;
}
case BLANK: {
*pt_bitmap = ' ' | attribute;
/* DONT move the cursor... */
return;
}
default: {
*pt_bitmap = (unsigned char)car | attribute;
advanceCursor();
return;
}
}
}
/* trivial state machine to handle escape sequences:
*
* ---------------------------------
* | |
* | |
* KEY: esc V [ DCABHKJ esc |
* STATE: 0 -----> 27 -----> '[' ----------> -1 -----
* ^\ \ \ \
* KEY: | \other \ other \ other \ other
* <-------------------------------------
*
* in state '-1', the DCABHKJ cases are handled
*
* (cursor motion and screen clearing)
*/
#define DONE (-1)
static int
handleEscape(int oldState, char car)
{
int rval = 0;
int ro,co;
switch ( oldState ) {
case DONE: /* means the previous char terminated an ESC sequence... */
case 0:
if ( 27 == car ) {
rval = 27; /* START of an ESC sequence */
}
break;
case 27:
if ( '[' == car ) {
rval = car; /* received ESC '[', so far */
} else {
/* dump suppressed 'ESC'; outch will append the char */
videoPutChar(ESC);
}
break;
case '[':
/* handle 'ESC' '[' sequences here */
ro = row; co = column;
rval = DONE; /* done */
switch (car) {
case 'D': /* left */
if ( co > 0 ) co--;
break;
case 'C': /* right */
if ( co < maxCol ) co++;
break;
case 'A': /* up */
if ( ro > 0 ) ro--;
break;
case 'B': /* down */
if ( ro < maxRow ) ro++;
break;
case 'H': /* home */
ro = co = 0;
break;
case 'K': /* clear to end of line */
while ( column < maxCol - 1 )
videoPutChar(' ');
videoPutChar(BLANK);
break;
case 'J': /* clear to end of screen */
while ( ((row < maxRow-1) || (column < maxCol-1)) )
videoPutChar(' ');
videoPutChar(BLANK);
break;
default:
videoPutChar(ESC);
videoPutChar('[');
/* DONT move the cursor */
ro = -1;
rval = 0;
break;
}
/* reset cursor */
if ( ro >= 0)
gotorc(ro,co);
default:
break;
}
return rval;
}
static void
clear_screen(void)
{
int i,j;
for (j = 0; j <= maxRow; j++) {
for (i = 0; i <= maxCol; i++) {
videoPutChar(' ');
}
}
column = 0;
row = 0;
}
/*-------------------------------------------------------------------------+
| Function: _IBMPC_outch
| Description: Higher level (console) interface to consPutc.
| Global Variables: None.
| Arguments: c - character to write to console.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
_IBMPC_outch(char c)
{
static int escaped = 0;
if ( ! (escaped = handleEscape(escaped, c)) ) {
if ( '\n' == c )
videoPutChar('\r');
videoPutChar(c);
}
} /* _IBMPC_outch */
/*-------------------------------------------------------------------------+
| Function: _IBMPC_initVideo
| Description: Video system initialization. Hook for any early setup.
| Global Variables: bitMapBaseAddr, ioCrtBaseAddr, maxCol, maxRow, row
| column, attribute, nLines;
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
_IBMPC_initVideo(void)
{
unsigned char* pt = (unsigned char*) (VIDEO_MODE_ADDR);
if (*pt == VGAMODE7) {
bitMapBaseAddr = (unsigned short*) V_MONO;
}
else {
bitMapBaseAddr = (unsigned short*) V_COLOR;
}
ioCrtBaseAddr = *(unsigned short*) DISPLAY_CRT_BASE_IO_ADDR;
maxCol = * (unsigned short*) NB_MAX_COL_ADDR;
maxRow = * (unsigned char*) NB_MAX_ROW_ADDR;
column = 0;
row = 0;
attribute = ((BLACK << 4) | WHITE)<<8;
nLines = 0;
clear_screen();
#ifdef DEBUG_EARLY_STAGE
printk("bitMapBaseAddr = %X, display controller base IO = %X\n",
(unsigned) bitMapBaseAddr,
(unsigned) ioCrtBaseAddr);
videoPrintf("maxCol = %d, maxRow = %d\n", (unsigned) maxCol, (unsigned) maxRow);
#endif
} /* _IBMPC_initVideo */
/* for old DOS compatibility n-curses type of applications */
void gotoxy( int x, int y );
int whereX( void );
int whereY( void );
void gotoxy( int x, int y )
{
gotorc(y,x);
}
int whereX( void )
{
return row;
}
int whereY( void )
{
return column;
}

View File

@@ -1,627 +0,0 @@
/*
* linux/drivers/char/pc_keyb.c
*
* Separation of the PC low-level part by Geert Uytterhoeven, May 1997
* See keyboard.c for the whole history.
*
* Major cleanup by Martin Mares, May 1997
*
* Combined the keyboard and PS/2 mouse handling into one file,
* because they share the same hardware.
* Johan Myreen <jem@iki.fi> 1998-10-08.
*
* Code fixes to handle mouse ACKs properly.
* C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
*
* Ported to RTEMS by Rosimildo da Silva
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <bsp.h>
#include <rtems/keyboard.h>
#include "i386kbd.h"
static unsigned char handle_kbd_event(void);
static void kbd_write_command_w(int data);
static void kbd_write_output_w(int data);
/* Some configuration switches are present in the include file... */
/* Simple translation table for the SysRq keys */
#ifdef CONFIG_MAGIC_SYSRQ
unsigned char pckbd_sysrq_xlate[128] =
"\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
"qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
"dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
"bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
"\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
"\r\000/"; /* 0x60 - 0x6f */
#endif
/* used only by send_data - set by keyboard_interrupt */
static volatile unsigned char reply_expected = 0;
static volatile unsigned char acknowledge = 0;
static volatile unsigned char resend = 0;
/*
* Translation of escaped scancodes to keycodes.
* This is now user-settable.
* The keycodes 1-88,96-111,119 are fairly standard, and
* should probably not be changed - changing might confuse X.
* X also interprets scancode 0x5d (KEY_Begin).
*
* For 1-88 keycode equals scancode.
*/
#define E0_KPENTER 96
#define E0_RCTRL 97
#define E0_KPSLASH 98
#define E0_PRSCR 99
#define E0_RALT 100
#define E0_BREAK 101 /* (control-pause) */
#define E0_HOME 102
#define E0_UP 103
#define E0_PGUP 104
#define E0_LEFT 105
#define E0_RIGHT 106
#define E0_END 107
#define E0_DOWN 108
#define E0_PGDN 109
#define E0_INS 110
#define E0_DEL 111
#define E1_PAUSE 119
/*
* The keycodes below are randomly located in 89-95,112-118,120-127.
* They could be thrown away (and all occurrences below replaced by 0),
* but that would force many users to use the `setkeycodes' utility, where
* they needed not before. It does not matter that there are duplicates, as
* long as no duplication occurs for any single keyboard.
*/
#define SC_LIM 89
#define FOCUS_PF1 85 /* actual code! */
#define FOCUS_PF2 89
#define FOCUS_PF3 90
#define FOCUS_PF4 91
#define FOCUS_PF5 92
#define FOCUS_PF6 93
#define FOCUS_PF7 94
#define FOCUS_PF8 95
#define FOCUS_PF9 120
#define FOCUS_PF10 121
#define FOCUS_PF11 122
#define FOCUS_PF12 123
#define JAP_86 124
/* tfj@olivia.ping.dk:
* The four keys are located over the numeric keypad, and are
* labelled A1-A4. It's an rc930 keyboard, from
* Regnecentralen/RC International, Now ICL.
* Scancodes: 59, 5a, 5b, 5c.
*/
#define RGN1 124
#define RGN2 125
#define RGN3 126
#define RGN4 127
static unsigned char high_keys[128 - SC_LIM] = {
RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */
0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */
FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */
FOCUS_PF8, JAP_86, FOCUS_PF10, 0 /* 0x7c-0x7f */
};
/* BTC */
#define E0_MACRO 112
/* LK450 */
#define E0_F13 113
#define E0_F14 114
#define E0_HELP 115
#define E0_DO 116
#define E0_F17 117
#define E0_KPMINPLUS 118
/*
* My OmniKey generates e0 4c for the "OMNI" key and the
* right alt key does nada. [kkoller@nyx10.cs.du.edu]
*/
#define E0_OK 124
/*
* New microsoft keyboard is rumoured to have
* e0 5b (left window button), e0 5c (right window button),
* e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
* [or: Windows_L, Windows_R, TaskMan]
*/
#define E0_MSLW 125
#define E0_MSRW 126
#define E0_MSTM 127
static unsigned char e0_keys[128] = {
0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */
E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */
E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */
E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */
0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */
};
static void mdelay( unsigned long t )
{
Wait_X_ms( t );
}
int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
{
if (scancode < SC_LIM || scancode > 255 || keycode > 127)
return -EINVAL;
if (scancode < 128)
high_keys[scancode - SC_LIM] = keycode;
else
e0_keys[scancode - 128] = keycode;
return 0;
}
int pckbd_getkeycode(unsigned int scancode)
{
return
(scancode < SC_LIM || scancode > 255) ? -EINVAL :
(scancode < 128) ? high_keys[scancode - SC_LIM] :
e0_keys[scancode - 128];
}
static int do_acknowledge(unsigned char scancode)
{
if (reply_expected) {
/* Unfortunately, we must recognise these codes only if we know they
* are known to be valid (i.e., after sending a command), because there
* are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
* keys with such codes :(
*/
if (scancode == KBD_REPLY_ACK) {
acknowledge = 1;
reply_expected = 0;
return 0;
} else if (scancode == KBD_REPLY_RESEND) {
resend = 1;
reply_expected = 0;
return 0;
}
/* Should not happen... */
printk( "keyboard reply expected - got %02x\n", scancode);
}
return 1;
}
int pckbd_translate(unsigned char scancode, unsigned char *keycode,
char raw_mode)
{
static int prev_scancode = 0;
/* special prefix scancodes.. */
if (scancode == 0xe0 || scancode == 0xe1) {
prev_scancode = scancode;
return 0;
}
/* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
if (scancode == 0x00 || scancode == 0xff) {
prev_scancode = 0;
return 0;
}
scancode &= 0x7f;
if (prev_scancode) {
/*
* usually it will be 0xe0, but a Pause key generates
* e1 1d 45 e1 9d c5 when pressed, and nothing when released
*/
if (prev_scancode != 0xe0) {
if (prev_scancode == 0xe1 && scancode == 0x1d) {
prev_scancode = 0x100;
return 0;
} else if (prev_scancode == 0x100 && scancode == 0x45) {
*keycode = E1_PAUSE;
prev_scancode = 0;
} else {
#ifdef KBD_REPORT_UNKN
if (!raw_mode)
printk("keyboard: unknown e1 escape sequence\n");
#endif
prev_scancode = 0;
return 0;
}
} else {
prev_scancode = 0;
/*
* The keyboard maintains its own internal caps lock and
* num lock statuses. In caps lock mode E0 AA precedes make
* code and E0 2A follows break code. In num lock mode,
* E0 2A precedes make code and E0 AA follows break code.
* We do our own book-keeping, so we will just ignore these.
*/
/*
* For my keyboard there is no caps lock mode, but there are
* both Shift-L and Shift-R modes. The former mode generates
* E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
* So, we should also ignore the latter. - aeb@cwi.nl
*/
if (scancode == 0x2a || scancode == 0x36)
return 0;
if (e0_keys[scancode])
*keycode = e0_keys[scancode];
else {
#ifdef KBD_REPORT_UNKN
if (!raw_mode)
printk( "keyboard: unknown scancode e0 %02x\n",
scancode);
#endif
return 0;
}
}
} else if (scancode >= SC_LIM) {
/* This happens with the FOCUS 9000 keyboard
Its keys PF1..PF12 are reported to generate
55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
Moreover, unless repeated, they do not generate
key-down events, so we have to zero up_flag below */
/* Also, Japanese 86/106 keyboards are reported to
generate 0x73 and 0x7d for \ - and \ | respectively. */
/* Also, some Brazilian keyboard is reported to produce
0x73 and 0x7e for \ ? and KP-dot, respectively. */
*keycode = high_keys[scancode - SC_LIM];
if (!*keycode) {
if (!raw_mode) {
#ifdef KBD_REPORT_UNKN
printk( "keyboard: unrecognized scancode (%02x)"
" - ignored\n", scancode);
#endif
}
return 0;
}
} else
*keycode = scancode;
return 1;
}
char pckbd_unexpected_up(unsigned char keycode)
{
/* unexpected, but this can happen: maybe this was a key release for a
FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */
if (keycode >= SC_LIM || keycode == 85)
return 0;
else
return 0200;
}
static void kb_wait(void)
{
unsigned long timeout = KBC_TIMEOUT;
do {
/*
* "handle_kbd_event()" will handle any incoming events
* while we wait - keypresses or mouse movement.
*/
unsigned char status = handle_kbd_event();
if (! (status & KBD_STAT_IBF))
return;
mdelay(1);
timeout--;
} while (timeout);
#ifdef KBD_REPORT_TIMEOUTS
printk( "Keyboard timed out[1]\n");
#endif
}
/*
* This reads the keyboard status port, and does the
* appropriate action.
*
* It requires that we hold the keyboard controller
* spinlock.
*/
static unsigned char handle_kbd_event(void)
{
unsigned char status = kbd_read_status();
unsigned int work = 10000;
while (status & KBD_STAT_OBF) {
unsigned char scancode;
scancode = kbd_read_input();
if (status & KBD_STAT_MOUSE_OBF) {
#if 0
handle_mouse_event(scancode);
#endif
} else {
if (do_acknowledge(scancode))
handle_scancode(scancode, !(scancode & 0x80));
mark_bh(KEYBOARD_BH);
}
status = kbd_read_status();
if(!work--)
{
printk( "pc_keyb: controller jammed (0x%02X).\n", status);
break;
}
return status;
}
/*
* the commands to set the leds for some reason, returns 0x14, 0x16
* and I am intepreting as an ACK, because the original code from
* Linux was timeing out here...
*/
acknowledge = 1;
reply_expected = 0;
resend = 0;
return status;
}
void keyboard_interrupt(void *unused)
{
handle_kbd_event();
}
/*
* send_data sends a character to the keyboard and waits
* for an acknowledge, possibly retrying if asked to. Returns
* the success status.
*
* Don't use 'jiffies', so that we don't depend on interrupts
*/
static int send_data(unsigned char data)
{
int retries = 3;
do {
unsigned long timeout = KBD_TIMEOUT;
acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */
resend = 0;
reply_expected = 1;
kbd_write_output_w(data);
for (;;) {
if (acknowledge)
return 1;
if (resend)
break;
mdelay(1);
if (!--timeout) {
#ifdef KBD_REPORT_TIMEOUTS
printk("Keyboard timeout[2]\n");
#endif
return 0;
}
}
} while (retries-- > 0);
#ifdef KBD_REPORT_TIMEOUTS
printk( "keyboard: Too many NACKs -- noisy kbd cable?\n");
#endif
return 0;
}
void pckbd_leds(unsigned char leds)
{
if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))
send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */
}
/*
* In case we run on a non-x86 hardware we need to initialize both the
* keyboard controller and the keyboard. On a x86, the BIOS will
* already have initialized them.
*
* Some x86 BIOSes do not correctly initialize the keyboard, so the
* "kbd-reset" command line options can be given to force a reset.
* [Ranger]
*/
#ifdef __i386__
int kbd_startup_reset = 0;
#else
int kbd_startup_reset = 1;
#endif
/* for "kbd-reset" cmdline param */
void kbd_reset_setup(char *str, int *ints)
{
kbd_startup_reset = 1;
}
#define KBD_NO_DATA (-1) /* No data */
#define KBD_BAD_DATA (-2) /* Parity or other error */
static int kbd_read_data(void)
{
int retval = KBD_NO_DATA;
unsigned char status;
status = kbd_read_status();
if (status & KBD_STAT_OBF) {
unsigned char data = kbd_read_input();
retval = data;
if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
retval = KBD_BAD_DATA;
}
return retval;
}
static void kbd_clear_input(void)
{
int maxread = 100; /* Random number */
do {
if (kbd_read_data() == KBD_NO_DATA)
break;
} while (--maxread);
}
static int kbd_wait_for_input(void)
{
long timeout = KBD_INIT_TIMEOUT;
do {
int retval = kbd_read_data();
if (retval >= 0)
return retval;
mdelay(1);
} while (--timeout);
return -1;
}
static void kbd_write_command_w(int data)
{
kb_wait();
kbd_write_command(data);
}
static void kbd_write_output_w(int data)
{
kb_wait();
kbd_write_output(data);
}
static char * initialize_kbd(void)
{
int status;
/*
* Test the keyboard interface.
* This seems to be the only way to get it going.
* If the test is successful a x55 is placed in the input buffer.
*/
kbd_write_command_w(KBD_CCMD_SELF_TEST);
if (kbd_wait_for_input() != 0x55)
return "Keyboard failed self test";
/*
* Perform a keyboard interface test. This causes the controller
* to test the keyboard clock and data lines. The results of the
* test are placed in the input buffer.
*/
kbd_write_command_w(KBD_CCMD_KBD_TEST);
if (kbd_wait_for_input() != 0x00)
return "Keyboard interface failed self test";
/*
* Enable the keyboard by allowing the keyboard clock to run.
*/
kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
/*
* Reset keyboard. If the read times out
* then the assumption is that no keyboard is
* plugged into the machine.
* This defaults the keyboard to scan-code set 2.
*
* Set up to try again if the keyboard asks for RESEND.
*/
do {
kbd_write_output_w(KBD_CMD_RESET);
status = kbd_wait_for_input();
if (status == KBD_REPLY_ACK)
break;
if (status != KBD_REPLY_RESEND)
return "Keyboard reset failed, no ACK";
} while (1);
if (kbd_wait_for_input() != KBD_REPLY_POR)
return "Keyboard reset failed, no POR";
/*
* Set keyboard controller mode. During this, the keyboard should be
* in the disabled state.
*
* Set up to try again if the keyboard asks for RESEND.
*/
do {
kbd_write_output_w(KBD_CMD_DISABLE);
status = kbd_wait_for_input();
if (status == KBD_REPLY_ACK)
break;
if (status != KBD_REPLY_RESEND)
return "Disable keyboard: no ACK";
} while (1);
kbd_write_command_w(KBD_CCMD_WRITE_MODE);
kbd_write_output_w(KBD_MODE_KBD_INT
| KBD_MODE_SYS
| KBD_MODE_DISABLE_MOUSE
| KBD_MODE_KCC);
/* ibm powerpc portables need this to use scan-code set 1 -- Cort */
kbd_write_command_w(KBD_CCMD_READ_MODE);
if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
/*
* If the controller does not support conversion,
* Set the keyboard to scan-code set 1.
*/
kbd_write_output_w(0xF0);
kbd_wait_for_input();
kbd_write_output_w(0x01);
kbd_wait_for_input();
}
kbd_write_output_w(KBD_CMD_ENABLE);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Enable keyboard: no ACK";
/*
* Finally, set the typematic rate to maximum.
*/
kbd_write_output_w(KBD_CMD_SET_RATE);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Set rate: no ACK";
kbd_write_output_w(0x00);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Set rate: no ACK";
return NULL;
}
void pckbd_init_hw(void)
{
/* kbd_request_region(); */
/* Flush any pending input. */
kbd_clear_input();
if (kbd_startup_reset) {
char *msg = initialize_kbd();
if (msg)
printk( "initialize_kbd: %s\n", msg);
}
#if defined CONFIG_PSMOUSE
psaux_init();
#endif
/* Ok, finally allocate the IRQ, and off we go.. */
#if 0
kbd_request_irq( keyboard_interrupt );
#endif
}

View File

@@ -1,84 +0,0 @@
/*
* @file
*
* @ingroup Console
*
* @brief printk support routines
*
* This file contains the required printk support.
*/
/*
* COPYRIGHT (c) 1989-2012.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems.h>
#include <rtems/bspIo.h>
#if BSP_ENABLE_VGA
#include <rtems/keyboard.h>
#endif
#include <bsp.h>
#include <libchip/serial.h>
#include <libchip/ns16550.h>
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
rtems_device_minor_number BSPPrintkPort = 0;
void BSP_outch(char ch);
int BSP_inch(void);
void BSP_outch(char ch)
{
#if BSP_ENABLE_VGA
bool isVga = BSPPrintkPort == BSP_CONSOLE_VGA;
#else
bool isVga = false;
#endif
if ( !isVga ) {
console_tbl *port = Console_Port_Tbl[BSPPrintkPort];
if (port->pDeviceFns && port->pDeviceFns->deviceWritePolled) {
port->pDeviceFns->deviceWritePolled( BSPPrintkPort, ch );
}
return;
}
#if BSP_ENABLE_VGA
_IBMPC_outch( ch );
#endif
}
int BSP_inch(void)
{
#if BSP_ENABLE_VGA
bool isVga = BSPPrintkPort == BSP_CONSOLE_VGA;
#else
bool isVga = false;
#endif
int result = -1;
if ( !isVga ) {
console_tbl *port = Console_Port_Tbl[BSPPrintkPort];
if (port->pDeviceFns && port->pDeviceFns->deviceRead) {
do {
result = port->pDeviceFns->deviceRead( BSPPrintkPort );
} while (result == -1);
return result;
}
}
#if BSP_ENABLE_VGA
result = BSP_wait_polled_input();
#endif
return result;
}
BSP_output_char_function_type BSP_output_char = BSP_outch;
BSP_polling_getchar_function_type BSP_poll_char = BSP_inch;

View File

@@ -1,562 +0,0 @@
/*
* linux/drivers/char/pc_keyb.c
* Separation of the PC low-level part by Geert Uytterhoeven, May 1997
* See keyboard.c for the whole history.
* Major cleanup by Martin Mares, May 1997
* Combined the keyboard and PS/2 mouse handling into one file,
* because they share the same hardware.
* Johan Myreen <jem@iki.fi> 1998-10-08.
* Code fixes to handle mouse ACKs properly.
* C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
*
* RTEMS port: by Rosimildo da Silva.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <assert.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <rtems/libio.h>
#include <termios.h>
#include <i386_io.h>
#include <rtems/mw_uid.h>
#include <rtems/mouse_parser.h>
#define INITIALIZE_MOUSE
/* Some configuration switches are present in the include file... */
#include <rtems/ps2_drv.h>
#include "ps2_mouse.h"
static void kbd_write_command_w(int data);
#if 0
static void kbd_write_output_w(int data);
#endif
static unsigned char handle_kbd_event(void);
static void ps2_set_driver_handler(int port, mouse_parser_enqueue_handler handler);
/* used only by send_data - set by keyboard_interrupt */
static volatile unsigned char reply_expected = 0;
static volatile unsigned char acknowledge = 0;
static volatile unsigned char resend = 0;
/*
* PS/2 Auxiliary Device
*/
static int psaux_init(void);
static struct aux_queue *queue; /* Mouse data buffer. */
static int aux_count = 0;
/* used when we send commands to the mouse that expect an ACK. */
static unsigned char mouse_reply_expected = 0;
#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)
#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
#define MAX_RETRIES 60 /* some aux operations take long time*/
static void ps2_mouse_interrupt(void *);
static mouse_parser_enqueue_handler driver_input_handler_ps2 = NULL;
/*
* This routine sets the handler to handle the characters received
* from the serial port.
*/
static void ps2_set_driver_handler(
int port,
mouse_parser_enqueue_handler handler
)
{
driver_input_handler_ps2 = handler;
}
static void mdelay( unsigned long t )
{
Wait_X_ms( t );
}
static void* termios_ttyp_paux = NULL;
/*
* Wait for keyboard controller input buffer to drain.
*
* Don't use 'jiffies' so that we don't depend on
* interrupts..
*
* Quote from PS/2 System Reference Manual:
*
* "Address hex 0060 and address hex 0064 should be written only when
* the input-buffer-full bit and output-buffer-full bit in the
* Controller Status register are set 0."
*/
static void kb_wait(void)
{
unsigned long timeout = KBC_TIMEOUT;
do {
/*
* "handle_kbd_event()" will handle any incoming events
* while we wait - keypresses or mouse movement.
*/
unsigned char status = handle_kbd_event();
if (! (status & KBD_STAT_IBF))
return;
mdelay(1);
timeout--;
} while (timeout);
#ifdef KBD_REPORT_TIMEOUTS
printk( "Keyboard timed out[1]\n");
#endif
}
static int do_acknowledge(unsigned char scancode)
{
if (reply_expected) {
/* Unfortunately, we must recognise these codes only if we know they
* are known to be valid (i.e., after sending a command), because there
* are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
* keys with such codes :(
*/
if (scancode == KBD_REPLY_ACK) {
acknowledge = 1;
reply_expected = 0;
return 0;
} else if (scancode == KBD_REPLY_RESEND) {
resend = 1;
reply_expected = 0;
return 0;
}
/* Should not happen... */
#if 0
printk( "keyboard reply expected - got %02x\n", scancode);
#endif
}
return 1;
}
static inline void handle_mouse_event(unsigned char scancode)
{
if (mouse_reply_expected) {
if (scancode == AUX_ACK) {
mouse_reply_expected--;
return;
}
mouse_reply_expected = 0;
}
if (aux_count) {
int head = queue->head;
queue->buf[head] = scancode;
head = (head + 1) & (AUX_BUF_SIZE-1);
if (head != queue->tail) {
queue->head = head;
}
/* if the input queue is active, add to it */
if( driver_input_handler_ps2 ) {
driver_input_handler_ps2( &scancode, 1 );
} else {
/* post this byte to termios */
rtems_termios_enqueue_raw_characters( termios_ttyp_paux, (char *)&scancode, 1 );
}
}
}
/*
* This reads the keyboard status port, and does the
* appropriate action.
*
* It requires that we hold the keyboard controller
* spinlock.
*/
static unsigned char handle_kbd_event(void)
{
unsigned char status = kbd_read_status();
unsigned int work = 10000;
while (status & KBD_STAT_OBF) {
unsigned char scancode;
scancode = kbd_read_input();
if (status & KBD_STAT_MOUSE_OBF) {
handle_mouse_event(scancode);
} else {
do_acknowledge(scancode);
printk("pc_keyb: %X ", scancode );
}
status = kbd_read_status();
if(!work--) {
printk("pc_keyb: controller jammed (0x%02X).\n", status);
break;
}
}
return status;
}
static void ps2_mouse_interrupt(void * unused)
{
handle_kbd_event();
}
static void kbd_write_command_w(int data)
{
kb_wait();
kbd_write_command(data);
}
static void kbd_write_cmd(int cmd)
{
kb_wait();
kbd_write_command(KBD_CCMD_WRITE_MODE);
kb_wait();
kbd_write_output(cmd);
}
/*
* Check if this is a dual port controller.
*/
static int detect_auxiliary_port(void)
{
int loops = 10;
int retval = 0;
/* Put the value 0x5A in the output buffer using the "Write
* Auxiliary Device Output Buffer" command (0xD3). Poll the
* Status Register for a while to see if the value really
* turns up in the Data Register. If the KBD_STAT_MOUSE_OBF
* bit is also set to 1 in the Status Register, we assume this
* controller has an Auxiliary Port (a.k.a. Mouse Port).
*/
kb_wait();
kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF);
kb_wait();
kbd_write_output(0x5a); /* 0x5a is a random dummy value. */
do {
unsigned char status = kbd_read_status();
if (status & KBD_STAT_OBF) {
kbd_read_input();
if (status & KBD_STAT_MOUSE_OBF) {
printk( "Detected PS/2 Mouse Port.\n");
retval = 1;
}
break;
}
mdelay(1);
} while (--loops);
return retval;
}
/*
* Send a byte to the mouse.
*/
static void aux_write_dev(int val)
{
kb_wait();
kbd_write_command(KBD_CCMD_WRITE_MOUSE);
kb_wait();
kbd_write_output(val);
}
/*
* Send a byte to the mouse & handle returned ack
*/
static void aux_write_ack(int val)
{
kb_wait();
kbd_write_command(KBD_CCMD_WRITE_MOUSE);
kb_wait();
kbd_write_output(val);
/* we expect an ACK in response. */
mouse_reply_expected++;
kb_wait();
}
static unsigned char get_from_queue(void)
{
unsigned char result;
result = queue->buf[queue->tail];
queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
return result;
}
static int queue_empty(void)
{
return queue->head == queue->tail;
}
/*
* Random magic cookie for the aux device
*/
#define AUX_DEV ((void *)queue)
static int release_aux(void)
{
rtems_status_code status;
if (--aux_count)
return 0;
kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */
kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE);
status = rtems_interrupt_handler_remove(
AUX_IRQ,
ps2_mouse_interrupt,
NULL
);
assert(status == RTEMS_SUCCESSFUL);
return 0;
}
/*
* Install interrupt handler.
* Enable auxiliary device.
*/
static int open_aux(void)
{
rtems_status_code status;
if (aux_count++) {
return 0;
}
queue->head = queue->tail = 0; /* Flush input queue */
status = rtems_interrupt_handler_install(
AUX_IRQ,
"ps2_mouse",
RTEMS_INTERRUPT_UNIQUE,
ps2_mouse_interrupt,
NULL
);
assert(status == RTEMS_SUCCESSFUL);
kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable the auxiliary port on
controller. */
aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */
kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */
return 0;
}
/*
* Put bytes from input queue to buffer.
*/
size_t read_aux(char * buffer, size_t count )
{
size_t i = count;
unsigned char c;
if (queue_empty()) {
return 0;
}
while (i > 0 && !queue_empty()) {
c = get_from_queue();
*buffer++ = c;
i--;
}
return count-i;
}
/*
* Write to the aux device.
*/
static int write_aux( int minor, const char * buffer, int count )
{
int retval = 0;
if (count) {
int written = 0;
if (count > 32)
count = 32; /* Limit to 32 bytes. */
do {
char c;
c = *buffer++;
aux_write_dev(c);
written++;
} while (--count);
retval = -EIO;
if (written) {
retval = written;
}
}
return retval;
}
static int psaux_init( void )
{
if( !detect_auxiliary_port() ) {
printk( "PS/2 - mouse not found.\n" );
return -EIO;
}
queue = (struct aux_queue *)malloc( sizeof(*queue) );
memset(queue, 0, sizeof(*queue));
queue->head = queue->tail = 0;
queue->proc_list = NULL;
#ifdef INITIALIZE_MOUSE
kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */
aux_write_ack(AUX_SET_SAMPLE);
aux_write_ack(100); /* 100 samples/sec */
aux_write_ack(AUX_SET_RES);
aux_write_ack(3); /* 8 counts per mm */
aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */
#endif /* INITIALIZE_MOUSE */
kbd_write_command(KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */
kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */
return 0;
}
/*
* paux device driver INITIALIZE entry point.
*/
rtems_device_driver paux_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_status_code status;
/*
* Set up TERMIOS
*/
rtems_termios_initialize();
printk( "PS/2 mouse probe.\n" );
if( psaux_init() < 0 ) {
printk("Error detecting PS/2 mouse --\n");
/* we might want to finish the application here !!! */
}
open_aux();
/*
* Register the device
*/
status = rtems_io_register_name ("/dev/mouse", major, 0);
if (status != RTEMS_SUCCESSFUL) {
printk("Error registering paux device!\n");
rtems_fatal_error_occurred (status);
}
return RTEMS_SUCCESSFUL;
} /* tty_initialize */
static int paux_last_close(int major, int minor, void *arg)
{
release_aux();
return 0;
}
/*
* Write to the aux device. This routine is invoked by the
* termios framework whenever the "ECHO" feature is on.
* It does nothing write now.
*/
static ssize_t write_aux_echo( int minor, const char * buffer, size_t count )
{
return 0;
}
/*
* paux device driver OPEN entry point
*/
rtems_device_driver paux_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_status_code status;
static rtems_termios_callbacks cb =
{
NULL, /* firstOpen */
paux_last_close, /* lastClose */
NULL, /* poll read */
write_aux_echo, /* write */
NULL, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
0 /* outputUsesInterrupts */
};
status = rtems_termios_open (major, minor, arg, &cb );
termios_ttyp_paux = ( (rtems_libio_open_close_args_t *)arg)->iop->data1;
return status;
}
/*
* paux device driver CLOSE entry point
*/
rtems_device_driver paux_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return (rtems_termios_close (arg));
}
/*
* paux device driver READ entry point.
* Read characters from the PS/2 mouse.
*/
rtems_device_driver paux_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return rtems_termios_read (arg);
} /* tty_read */
/*
* paux device driver WRITE entry point.
* Write characters to the PS/2 mouse.
*/
rtems_device_driver paux_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
char *buffer = rw_args->buffer;
int maximum = rw_args->count;
rw_args->bytes_moved = write_aux( minor, buffer, maximum );
return RTEMS_SUCCESSFUL;
} /* tty_write */
/*
* Handle ioctl request.
*/
rtems_device_driver paux_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_ioctl_args_t *args = arg;
switch( args->command ) {
default:
return rtems_termios_ioctl (arg);
break;
case MW_UID_REGISTER_DEVICE:
printk( "PS2 Mouse: registering\n" );
mouse_parser_initialize( "ps2" );
ps2_set_driver_handler( minor, mouse_parser_enqueue );
break;
case MW_UID_UNREGISTER_DEVICE:
/*
unregister_mou_msg_queue( -1 );
*/
ps2_set_driver_handler( minor, NULL );
break;
}
args->ioctl_return = 0;
return RTEMS_SUCCESSFUL;
}

View File

@@ -1,151 +0,0 @@
/**
* @file
*
* @ingroup i386_pc386
*
* @brief Keyboard and mouse definitions.
*/
/*
* include/linux/pc_keyb.h
* PC Keyboard And Keyboard Controller
* (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*
* RTEMS port: by Rosimildo da Silva.
*
* This module was ported from Linux.
*
*/
/*
* Configuration Switches
*/
#undef KBD_REPORT_ERR /* Report keyboard errors */
#define KBD_REPORT_UNKN /* Report unknown scan codes */
#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */
#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */
#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */
#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */
/*
* Internal variables of the driver
*/
extern unsigned char pckbd_read_mask;
extern unsigned char aux_device_present;
/*
* Keyboard Controller Registers on normal PCs.
*/
#define KBD_STATUS_REG 0x64 /* Status register (R) */
#define KBD_CNTL_REG 0x64 /* Controller command register (W) */
#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */
/*
* Keyboard Controller Commands
*/
#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
initiated by the auxiliary device */
#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
/*
* Keyboard Commands
*/
#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
#define KBD_CMD_RESET 0xFF /* Reset */
/*
* Keyboard Replies
*/
#define KBD_REPLY_POR 0xAA /* Power on reset */
#define KBD_REPLY_ACK 0xFA /* Command ACK */
#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
/*
* Status Register Bits
*/
#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
#define KBD_STAT_PERR 0x80 /* Parity error */
#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
/*
* Controller Mode Register Bits
*/
#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
#define KBD_MODE_SYS 0x04 /* The system flag (?) */
#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
#define KBD_MODE_RFU 0x80
/*
* Mouse Commands
*/
#define AUX_SET_RES 0xE8 /* Set resolution */
#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
#define AUX_SET_STREAM 0xEA /* Set stream mode */
#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
#define AUX_RESET 0xFF /* Reset aux device */
#define AUX_ACK 0xFA /* Command byte ACK. */
#define AUX_BUF_SIZE 512 /* This might be better divisible by
three to make overruns stay in sync
but then the read function would need
a lock etc - ick */
struct aux_queue {
unsigned long head;
unsigned long tail;
struct wait_queue *proc_list;
struct fasync_struct *fasync;
unsigned char buf[AUX_BUF_SIZE];
};
/* How to access the keyboard macros on this platform. */
#define kbd_read_input() inb(KBD_DATA_REG)
#define kbd_read_status() inb(KBD_STATUS_REG)
#define kbd_write_output(val) outb(val, KBD_DATA_REG)
#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
/*
* Machine specific bits for the PS/2 driver
*/
#define AUX_IRQ 12

View File

@@ -1,109 +0,0 @@
/**
* @file
*
* @brief Driver for RTD316 ISA SCC Board
*
* The RTD316 has a single Z85C30.
*/
/*
* COPYRIGHT (c) 1989-2014.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <rtems/termiostypes.h>
#include <libchip/serial.h>
#include <libchip/z85c30.h>
#include <rtems/bspIo.h>
#include <bsp/rtd316.h>
#include <rtems/score/i386.h>
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
#define RTD_CLOCK_RATE (460800 * 32)
uint8_t rtd316_com_get_register(uint32_t addr, uint8_t reg)
{
register uint8_t val = 0;
outport_byte( addr, reg );
/* It appears the no delay is needed between the accesses. */
inport_byte( addr, val );
return val;
}
void rtd316_com_set_register(uint32_t addr,uint8_t reg, uint8_t val)
{
outport_byte( addr, reg );
/* It appears the no delay is needed between the accesses. */
outport_byte( addr, val );
}
rtems_device_driver rtd316_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor_arg,
void *arg
)
{
int p;
console_tbl *ports;
console_tbl *port_p;
/*
* Now allocate array of device structures and fill them in
*/
ports = calloc( 2, sizeof( console_tbl ) );
port_p = ports;
for ( p=0 ; p<2 ; p++ ) {
char name[32];
sprintf( name, "/dev/rtd316_1_%d", p );
printk("Found %s\n", name );
port_p->sDeviceName = strdup( name );
port_p->deviceType = SERIAL_Z85C30;
#if 0
port_p->pDeviceFns = &z85c30_fns_polled;
#else
port_p->pDeviceFns = &z85c30_fns;
#endif
port_p->deviceProbe = NULL;
port_p->pDeviceFlow = NULL;
port_p->ulMargin = 16;
port_p->ulHysteresis = 8;
port_p->pDeviceParams = (void *) 9600;
port_p->getRegister = rtd316_com_get_register;
port_p->setRegister = rtd316_com_set_register;
port_p->getData = NULL;
port_p->setData = NULL;
port_p->ulClock = RTD_CLOCK_RATE;
port_p->ulIntVector = 9;
if ( p==0 ) {
port_p->ulDataPort = 0;
port_p->ulCtrlPort1 = 0x340;
port_p->ulCtrlPort2 = 0x341;
} else {
port_p->ulDataPort = 1;
port_p->ulCtrlPort1 = 0x342;
port_p->ulCtrlPort2 = 0x343;
}
port_p++;
} /* end ports */
/*
* Register the devices
*/
console_register_devices( ports, 2 );
return RTEMS_SUCCESSFUL;
}

View File

@@ -1,48 +0,0 @@
/*
* COPYRIGHT (c) 1989-2011.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <bsp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <libchip/serial.h>
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
/* select which serial port the mouse is connected to */
#if defined(SERIAL_MOUSE_COM2)
#define MOUSE_DEVICE "/dev/com2"
#else
#define MOUSE_DEVICE "/dev/com1"
#endif
static const char *SerialMouseDevice = MOUSE_DEVICE;
bool bsp_get_serial_mouse_device(
const char **name,
const char **type
)
{
const char *consname;
*name = SerialMouseDevice;
*type = "ms";
/* Check if this port is not been used as console */
consname = Console_Port_Tbl[ Console_Port_Minor ]->sDeviceName;
if ( !strcmp(MOUSE_DEVICE, consname) ) {
printk( "SERIAL MOUSE: port selected as console.(%s)\n", *name );
rtems_fatal_error_occurred( -1 );
}
printk("Mouse Device: %s\n", *name );
return name;
}

View File

@@ -1,477 +0,0 @@
/*
* This file was brought over from FreeBSD for the PCI device table.
* The code for using the table is RTEMS specific is also under the
* FreeBSD license.
*
* COPYRIGHT (c) 1989-2012.
* On-Line Applications Research Corporation (OAR).
*/
/*-
* Copyright (c) 2006 Marcel Moolenaar
* Copyright (c) 2001 M. Warner Losh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __rtems__
#include <stddef.h>
#include <stdint.h>
#include <i386_io.h>
#else
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <dev/pci/pcivar.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_bus.h>
#endif
#define DEFAULT_RCLK 1843200
#ifndef __rtems__
static int uart_pci_probe(device_t dev);
static device_method_t uart_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, uart_pci_probe),
DEVMETHOD(device_attach, uart_bus_attach),
DEVMETHOD(device_detach, uart_bus_detach),
DEVMETHOD(device_resume, uart_bus_resume),
DEVMETHOD_END
};
static driver_t uart_pci_driver = {
uart_driver_name,
uart_pci_methods,
sizeof(struct uart_softc),
};
#endif
struct pci_id {
uint16_t vendor;
uint16_t device;
uint16_t subven;
uint16_t subdev;
const char *desc;
int rid;
int rclk;
int regshft;
};
static const struct pci_id pci_ns8250_ids[] = {
{ 0x1028, 0x0008, 0xffff, 0, "Dell Remote Access Card III", 0x14,
128 * DEFAULT_RCLK },
{ 0x1028, 0x0012, 0xffff, 0, "Dell RAC 4 Daughter Card Virtual UART", 0x14,
128 * DEFAULT_RCLK },
{ 0x1033, 0x0074, 0x1033, 0x8014, "NEC RCV56ACF 56k Voice Modem", 0x10 },
{ 0x1033, 0x007d, 0x1033, 0x8012, "NEC RS232C", 0x10 },
{ 0x103c, 0x1048, 0x103c, 0x1227, "HP Diva Serial [GSP] UART - Powerbar SP2",
0x10 },
{ 0x103c, 0x1048, 0x103c, 0x1301, "HP Diva RMP3", 0x14 },
{ 0x103c, 0x1290, 0xffff, 0, "HP Auxiliary Diva Serial Port", 0x18 },
{ 0x103c, 0x3301, 0xffff, 0, "HP iLO serial port", 0x10 },
{ 0x11c1, 0x0480, 0xffff, 0, "Agere Systems Venus Modem (V90, 56KFlex)", 0x14 },
{ 0x115d, 0x0103, 0xffff, 0, "Xircom Cardbus Ethernet + 56k Modem", 0x10 },
{ 0x1282, 0x6585, 0xffff, 0, "Davicom 56PDV PCI Modem", 0x10 },
{ 0x12b9, 0x1008, 0xffff, 0, "3Com 56K FaxModem Model 5610", 0x10 },
{ 0x131f, 0x1000, 0xffff, 0, "Siig CyberSerial (1-port) 16550", 0x18 },
{ 0x131f, 0x1001, 0xffff, 0, "Siig CyberSerial (1-port) 16650", 0x18 },
{ 0x131f, 0x1002, 0xffff, 0, "Siig CyberSerial (1-port) 16850", 0x18 },
{ 0x131f, 0x2000, 0xffff, 0, "Siig CyberSerial (1-port) 16550", 0x10 },
{ 0x131f, 0x2001, 0xffff, 0, "Siig CyberSerial (1-port) 16650", 0x10 },
{ 0x131f, 0x2002, 0xffff, 0, "Siig CyberSerial (1-port) 16850", 0x10 },
{ 0x135c, 0x0190, 0xffff, 0, "Quatech SSCLP-100", 0x18 },
{ 0x135c, 0x01c0, 0xffff, 0, "Quatech SSCLP-200/300", 0x18 },
{ 0x135e, 0x7101, 0xffff, 0, "Sealevel Systems Single Port RS-232/422/485/530",
0x18 },
{ 0x1407, 0x0110, 0xffff, 0, "Lava Computer mfg DSerial-PCI Port A", 0x10 },
{ 0x1407, 0x0111, 0xffff, 0, "Lava Computer mfg DSerial-PCI Port B", 0x10 },
{ 0x1407, 0x0510, 0xffff, 0, "Lava SP Serial 550 PCI", 0x10 },
{ 0x1409, 0x7168, 0x1409, 0x4025, "Timedia Technology Serial Port", 0x10,
8 * DEFAULT_RCLK },
{ 0x1409, 0x7168, 0x1409, 0x4027, "Timedia Technology Serial Port", 0x10,
8 * DEFAULT_RCLK },
{ 0x1409, 0x7168, 0x1409, 0x4028, "Timedia Technology Serial Port", 0x10,
8 * DEFAULT_RCLK },
{ 0x1409, 0x7168, 0x1409, 0x5025, "Timedia Technology Serial Port", 0x10,
8 * DEFAULT_RCLK },
{ 0x1409, 0x7168, 0x1409, 0x5027, "Timedia Technology Serial Port", 0x10,
8 * DEFAULT_RCLK },
{ 0x1415, 0x950b, 0xffff, 0, "Oxford Semiconductor OXCB950 Cardbus 16950 UART",
0x10, 16384000 },
{ 0x1415, 0xc120, 0xffff, 0, "Oxford Semiconductor OXPCIe952 PCIe 16950 UART",
0x10 },
{ 0x14e4, 0x4344, 0xffff, 0, "Sony Ericsson GC89 PC Card", 0x10},
{ 0x151f, 0x0000, 0xffff, 0, "TOPIC Semiconductor TP560 56k modem", 0x10 },
{ 0x1fd4, 0x1999, 0x1fd4, 0x0001, "Sunix SER5xxxx Serial Port", 0x10,
8 * DEFAULT_RCLK },
{ 0x8086, 0x0f0a, 0xffff, 0, "Intel ValleyView LPIO1 HSUART#1", 0x10,
24 * DEFAULT_RCLK, 2 },
{ 0x8086, 0x0f0c, 0xffff, 0, "Intel ValleyView LPIO1 HSUART#2", 0x10,
24 * DEFAULT_RCLK, 2 },
{ 0x8086, 0x1c3d, 0xffff, 0, "Intel AMT - KT Controller", 0x10 },
{ 0x8086, 0x1d3d, 0xffff, 0, "Intel C600/X79 Series Chipset KT Controller", 0x10 },
{ 0x8086, 0x2a07, 0xffff, 0, "Intel AMT - PM965/GM965 KT Controller", 0x10 },
{ 0x8086, 0x2a47, 0xffff, 0, "Mobile 4 Series Chipset KT Controller", 0x10 },
{ 0x8086, 0x2e17, 0xffff, 0, "4 Series Chipset Serial KT Controller", 0x10 },
{ 0x8086, 0x3b67, 0xffff, 0, "5 Series/3400 Series Chipset KT Controller",
0x10 },
{ 0x8086, 0x8811, 0xffff, 0, "Intel EG20T Serial Port 0", 0x10 },
{ 0x8086, 0x8812, 0xffff, 0, "Intel EG20T Serial Port 1", 0x10 },
{ 0x8086, 0x8813, 0xffff, 0, "Intel EG20T Serial Port 2", 0x10 },
{ 0x8086, 0x8814, 0xffff, 0, "Intel EG20T Serial Port 3", 0x10 },
{ 0x8086, 0x8c3d, 0xffff, 0, "Intel Lynx Point KT Controller", 0x10 },
{ 0x8086, 0x8cbd, 0xffff, 0, "Intel Wildcat Point KT Controller", 0x10 },
{ 0x8086, 0x9c3d, 0xffff, 0, "Intel Lynx Point-LP HECI KT", 0x10 },
{ 0x9710, 0x9820, 0x1000, 1, "NetMos NM9820 Serial Port", 0x10 },
{ 0x9710, 0x9835, 0x1000, 1, "NetMos NM9835 Serial Port", 0x10 },
{ 0x9710, 0x9865, 0xa000, 0x1000, "NetMos NM9865 Serial Port", 0x10 },
{ 0x9710, 0x9900, 0xa000, 0x1000,
"MosChip MCS9900 PCIe to Peripheral Controller", 0x10 },
{ 0x9710, 0x9901, 0xa000, 0x1000,
"MosChip MCS9901 PCIe to Peripheral Controller", 0x10 },
{ 0x9710, 0x9904, 0xa000, 0x1000,
"MosChip MCS9904 PCIe to Peripheral Controller", 0x10 },
{ 0x9710, 0x9922, 0xa000, 0x1000,
"MosChip MCS9922 PCIe to Peripheral Controller", 0x10 },
{ 0xdeaf, 0x9051, 0xffff, 0, "Middle Digital PC Weasel Serial Port", 0x10 },
{ 0xffff, 0, 0xffff, 0, NULL, 0, 0}
};
#ifndef __rtems__
const static struct pci_id *
uart_pci_match(device_t dev, const struct pci_id *id)
{
uint16_t device, subdev, subven, vendor;
vendor = pci_get_vendor(dev);
device = pci_get_device(dev);
while (id->vendor != 0xffff &&
(id->vendor != vendor || id->device != device))
id++;
if (id->vendor == 0xffff)
return (NULL);
if (id->subven == 0xffff)
return (id);
subven = pci_get_subvendor(dev);
subdev = pci_get_subdevice(dev);
while (id->vendor == vendor && id->device == device &&
(id->subven != subven || id->subdev != subdev))
id++;
return ((id->vendor == vendor && id->device == device) ? id : NULL);
}
static int
uart_pci_probe(device_t dev)
{
struct uart_softc *sc;
const struct pci_id *id;
int result;
sc = device_get_softc(dev);
id = uart_pci_match(dev, pci_ns8250_ids);
if (id != NULL) {
sc->sc_class = &uart_ns8250_class;
goto match;
}
/* Add checks for non-ns8250 IDs here. */
return (ENXIO);
match:
result = uart_bus_probe(dev, id->regshft, id->rclk, id->rid, 0);
/* Bail out on error. */
if (result > 0)
return (result);
/* Set/override the device description. */
if (id->desc)
device_set_desc(dev, id->desc);
return (result);
}
DRIVER_MODULE(uart, pci, uart_pci_driver, uart_devclass, NULL, NULL);
#endif
#ifdef __rtems__
#include <bsp.h>
#include <bsp/bspimpl.h>
#include <stdio.h>
#include <stdlib.h>
#include <libchip/serial.h>
#include <libchip/ns16550.h>
#include <rtems/bspIo.h>
#include <rtems/pci.h>
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
#define MAX_BOARDS 4
/*
* Information saved from PCI scan
*/
typedef struct {
bool found;
const char* desc;
uint32_t base;
uint8_t irq;
uint8_t bus;
uint8_t slot;
int ports;
uint32_t clock;
} port_instance_conf_t;
/*
* Memory Mapped Register Access Routines
*/
#define UART_PCI_IO (0)
static uint8_t pci_ns16550_mem_get_register(uint32_t addr, uint8_t i)
{
uint8_t val = 0;
volatile uint32_t *reg = (volatile uint32_t *)(addr + (i*4));
val = *reg;
if (UART_PCI_IO)
printk( "RD(%p -> 0x%02x) ", reg, val );
return val;
}
static void pci_ns16550_mem_set_register(uint32_t addr, uint8_t i, uint8_t val)
{
volatile uint32_t *reg = (volatile uint32_t *)(addr + (i*4));
if (UART_PCI_IO)
printk( "WR(%p <- 0x%02x) ", reg, val );
*reg = val;
}
/*
* IO Register Access Routines
*/
static uint8_t pci_ns16550_io_get_register(uint32_t addr, uint8_t i)
{
uint8_t val = rtems_inb(addr + i);
if (UART_PCI_IO)
printk( "RD(%p -> 0x%02x) ", (void*) addr + i, val );
return val;
}
static void pci_ns16550_io_set_register(uint32_t addr, uint8_t i, uint8_t val)
{
if (UART_PCI_IO)
printk( "WR(%p <- 0x%02x) ", (void*) addr + i, val );
rtems_outb(addr + i, val);
}
void pci_uart_probe(void)
{
port_instance_conf_t conf[MAX_BOARDS];
int boards = 0;
int b = 0;
console_tbl *ports;
console_tbl *port_p;
int bus;
int dev;
int fun;
int status;
int instance;
int i;
int total_ports = 0;
for ( b=0 ; b<MAX_BOARDS ; b++ ) {
conf[b].found = false;
}
/*
* Scan for Serial port boards
*/
for ( instance=0 ; instance < MAX_BOARDS ; instance++ ) {
for ( i=0 ; pci_ns8250_ids[i].vendor != 0xffff ; i++ ) {
if ( pci_ns8250_ids[i].vendor == 0xffff ) {
break;
}
/*
printk("Looking for 0x%04x:0x%04x\n",
pci_ns8250_ids[i].vendor,
pci_ns8250_ids[i].device);
*/
status = pci_find_device(
pci_ns8250_ids[i].vendor,
pci_ns8250_ids[i].device,
instance,
&bus,
&dev,
&fun
);
if ( status == PCIB_ERR_SUCCESS ) {
uint8_t irq;
uint32_t base;
bool io;
pci_read_config_dword( bus, dev, fun, PCI_BASE_ADDRESS_0, &base );
/*
* Reject memory mapped 64-bit boards. We need 2 BAR registers and the
* driver's base field is only 32-bits any way.
*/
io = (base & 1) == 1;
if (io || (!io && (((base >> 1) & 3) != 2))) {
boards++;
conf[instance].found = true;
conf[instance].desc = pci_ns8250_ids[i].desc;
conf[instance].clock = pci_ns8250_ids[i].rclk;
conf[instance].ports = 1;
total_ports += conf[instance].ports;
pci_read_config_byte( bus, dev, fun, PCI_INTERRUPT_LINE, &irq );
conf[instance].irq = irq;
conf[instance].base = base;
}
}
}
}
/*
* Now allocate array of device structures and fill them in
*/
if (boards) {
int device_instance;
ports = calloc( total_ports, sizeof( console_tbl ) );
if (ports != NULL) {
port_p = ports;
device_instance = 1;
for (b = 0; b < MAX_BOARDS; b++) {
uint32_t base = 0;
bool io;
const char* locatable = "";
const char* prefectable = locatable;
char name[32];
if ( conf[b].found == false )
continue;
sprintf( name, "/dev/pcicom%d", device_instance++ );
port_p->sDeviceName = strdup( name );
port_p->deviceType = SERIAL_NS16550;
if ( conf[b].irq <= 15 ) {
port_p->pDeviceFns = &ns16550_fns;
} else {
printk(
"%s IRQ=%d >= 16 requires APIC support, using polling\n",
name,
conf[b].irq
);
port_p->pDeviceFns = &ns16550_fns_polled;
}
/*
* PCI BAR (http://wiki.osdev.org/PCI#Base_Address_Registers):
*
* Bit 0: 0 = memory, 1 = IO
*
* Memory:
* Bit 2-1 : 0 = any 32bit address,
* 1 = < 1M
* 2 = any 64bit address
* Bit 3 : 0 = no, 1 = yes
* Bit 31-4 : base address (16-byte aligned)
*
* IO:
* Bit 1 : reserved
* Bit 31-2 : base address (4-byte aligned)
*/
io = (conf[b].base & 1) == 1;
if (io) {
base = conf[b].base & 0xfffffffc;
} else {
int loc = (conf[b].base >> 1) & 3;
if (loc == 0) {
base = conf[b].base & 0xfffffff0;
locatable = ",A32";
} else if (loc == 1) {
base = conf[b].base & 0x0000fff0;
locatable = ",A16";
}
prefectable = (conf[b].base & (1 << 3)) == 0 ? ",no-prefech" : ",prefetch";
}
port_p->deviceProbe = NULL;
port_p->pDeviceFlow = NULL;
port_p->ulMargin = 16;
port_p->ulHysteresis = 8;
port_p->pDeviceParams = (void *) 9600;
port_p->ulCtrlPort1 = base;
port_p->ulCtrlPort2 = 0; /* NA */
port_p->ulDataPort = 0; /* NA */
if (io) {
port_p->getRegister = pci_ns16550_io_get_register;
port_p->setRegister = pci_ns16550_io_set_register;
} else {
port_p->getRegister = pci_ns16550_mem_get_register;
port_p->setRegister = pci_ns16550_mem_set_register;
}
port_p->getData = NULL; /* NA */
port_p->setData = NULL; /* NA */
port_p->ulClock = conf[b].clock;
port_p->ulIntVector = conf[b].irq;
printk(
"%s:%d:%s,%s:0x%lx%s%s,irq:%d,clk:%lu\n", /* */
name, b, conf[b].desc,
io ? "io" : "mem", base, locatable, prefectable,
conf[b].irq, conf[b].clock
);
port_p++;
} /* end boards */
/*
* Register the devices
*/
console_register_devices( ports, total_ports );
/*
* Do not free the ports memory, the console hold this memory for-ever.
*/
}
}
}
#endif

View File

@@ -1,191 +0,0 @@
/*
* This file contains the termios TTY driver for the i386
* vga.
*
* COPYRIGHT (c) 1989-2011.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <rtems.h>
#include <rtems/libio.h>
#include <stdlib.h>
#include <libchip/serial.h>
#include <rtems/vgacons.h>
#include <rtems/keyboard.h>
#include <libchip/sersupp.h>
#include <bsp/irq.h>
#include <bsp.h>
#include <crt.h>
#include <assert.h>
#include <rtems/keyboard.h>
#define VGACONS_STATIC static
/*
* vgacons_init
*
* This function initializes the VGA console to a quiecsent state.
*/
VGACONS_STATIC void vgacons_init(int minor)
{
/*
* Note: We do not initialize the KBD interface here since
* it was initialized regardless of whether the
* vga is available or not. Therefore it is initialized
* in bsp_start.
*/
}
/*
* vgacons_open
*
* This function opens a port for communication.
*
* Default state is 9600 baud, 8 bits, No parity, and 1 stop bit.
*/
VGACONS_STATIC int vgacons_open(
int major,
int minor,
void *arg
)
{
return RTEMS_SUCCESSFUL;
}
/*
* vgacons_close
*
* This function shuts down the requested port.
*/
VGACONS_STATIC int vgacons_close(
int major,
int minor,
void *arg
)
{
return(RTEMS_SUCCESSFUL);
}
/*
* vgacons_write_polled
*
* This routine polls out the requested character.
*/
VGACONS_STATIC void vgacons_write_polled(
int minor,
char c
)
{
_IBMPC_outch( c );
if( c == '\n')
_IBMPC_outch( '\r' ); /* LF = LF + CR */
}
/*
* vgacons_write_support_polled
*
* Console Termios output entry point when using polled output.
*
*/
VGACONS_STATIC ssize_t vgacons_write_support_polled(
int minor,
const char *buf,
size_t len
)
{
int nwrite = 0;
/*
* poll each byte in the string out of the port.
*/
while (nwrite < len) {
vgacons_write_polled(minor, *buf++);
nwrite++;
}
/*
* return the number of bytes written.
*/
return nwrite;
}
/*
* vgacons_inbyte_nonblocking_polled
*
* Console Termios polling input entry point.
*/
VGACONS_STATIC int vgacons_inbyte_nonblocking_polled(
int minor
)
{
if( rtems_kbpoll() ) {
int c = getch();
return c;
}
return -1;
}
/*
* vgacons_set_attributes
*
* This function sets the UART channel to reflect the requested termios
* port settings.
*/
VGACONS_STATIC int vgacons_set_attributes(
int minor,
const struct termios *t
)
{
return 0;
}
bool vgacons_probe(
int minor
)
{
rtems_status_code status;
static bool firstTime = true;
if ((*(unsigned char*) NB_MAX_ROW_ADDR == 0) &&
(*(unsigned short*)NB_MAX_COL_ADDR == 0)) {
return false;
}
/*
* If there is a video card, let's assume there is also a keyboard.
* The means that we need the ISR installed in case someone wants to
* use the Keyboard or PS2 Mouse. With Microwindows, the console
* can be COM1 and you can still use the mouse/VGA for graphics.
*/
if ( firstTime ) {
status = rtems_interrupt_handler_install(
BSP_KEYBOARD,
"vgacons",
RTEMS_INTERRUPT_UNIQUE,
keyboard_interrupt,
NULL
);
assert(status == RTEMS_SUCCESSFUL);
}
firstTime = false;
return true;
}
const console_fns vgacons_fns =
{
libchip_serial_default_probe, /* deviceProbe */
vgacons_open, /* deviceFirstOpen */
vgacons_close, /* deviceLastClose */
vgacons_inbyte_nonblocking_polled, /* deviceRead */
vgacons_write_support_polled, /* deviceWrite */
vgacons_init, /* deviceInitialize */
vgacons_write_polled, /* deviceWritePolled */
vgacons_set_attributes, /* deviceSetAttributes */
FALSE, /* deviceOutputUsesInterrupts */
};

View File

@@ -1,757 +0,0 @@
/*
* Copyright (c) 1999 Greg Haerr <greg@censoft.com>
* Copyright (c) 1991 David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
* Alternate EGA/VGA Screen Driver Init, direct hw programming
*/
#include <i386_io.h>
#ifdef __rtems__
#define ROMFONT 0 /* =0 no bios rom fonts available*/
#else
#define ROMFONT 1 /* =1 uses PC rom fonts */
#endif
/* defines are defined in device.h of the MicroWindows package */
#define MODE_SET 0 /* draw pixels as given (default) */
#define MODE_XOR 1 /* draw pixels using XOR */
#define MODE_OR 2 /* draw pixels using OR (notimp)*/
#define MODE_AND 3 /* draw pixels using AND (notimp)*/
#define MODE_MAX 3
typedef int MODE; /* drawing mode*/
/* Define one and only one of the following to be nonzero*/
#define VGA_ET4000 0 /* TSENG LABS ET4000 chip 800x600*/
#define VGA_STANDARD 1 /* standard VGA 640x480*/
#define EGA_STANDARD 0 /* standard EGA 640x350*/
#define DONE 0
#define IN 1
#define OUT 2
#define RAM_SCAN_LINES 32 /* number of scan lines in fonts in RAM */
#define FONT_CHARS 256 /* number of characters in font tables */
#define CHAR_WIDTH 8 /* number of pixels for character width */
#define PALREG 0x3c0
#define SEQREG 0x3c4
#define SEQVAL 0x3c5
#define GRREG 0x3ce
#define GRVAL 0x3cf
#define ATTRREG 0x3da
#define CRTCREG 0x3d4
#define CRTCVAL 0x3d5
#define GENREG1 0x3c2
#define GENREG2 0x3cc
#define GENREG3 0x3ca
#define DATA_ROTATE 3 /* register number for data rotate */
typedef struct {
int action;
int port1;
int data1;
int port2;
int data2;
} REGIO;
#if ROMFONT
extern FARADDR rom_char_addr; /* address of ROM font*/
extern int ROM_CHAR_HEIGHT; /* ROM character height*/
#endif
/* local data*/
static REGIO graphics_on[];
static REGIO graph_off[];
/* entry points*/
void ega_hwinit(void);
void ega_hwterm(void);
/* local routines*/
static void writeregs(REGIO *rp);
static void out_word(unsigned int p,unsigned int d);
static void setmode(MODE mode);
void
ega_hwinit(void)
{
writeregs(graphics_on);
}
void
ega_hwterm(void)
{
setmode(MODE_SET);
/* Copy character table from ROM back into bit plane 2 before turning
* off graphics.
*/
out_word(SEQREG, 0x0100); /* syn reset */
out_word(SEQREG, 0x0402); /* cpu writes only to map 2 */
out_word(SEQREG, 0x0704); /* sequential addressing */
out_word(SEQREG, 0x0300); /* clear synchronous reset */
out_word(GRREG, 0x0204); /* select map 2 for CPU reads */
out_word(GRREG, 0x0005); /* disable odd-even addressing */
#if ROMFONT
{
FARADDR srcoffset;
FARADDR destoffset;
int data;
int ch;
int row;
srcoffset = rom_char_addr;
destoffset = EGA_BASE;
for (ch = 0; ch < FONT_CHARS; ch++) {
for(row = 0; row < ROM_CHAR_HEIGHT; row++) {
data = GETBYTE_FP(srcoffset++);
PUTBYTE_FP(destoffset++, data);
}
destoffset += (RAM_SCAN_LINES - ROM_CHAR_HEIGHT);
}
}
#endif
/* Finally set the registers back for text mode. */
writeregs(graph_off);
}
/* Set the graphics registers as indicated by the given table */
static void
writeregs(REGIO *rp)
{
for (; rp->action != DONE; rp++) {
switch (rp->action) {
case IN:
inp(rp->port1);
break;
case OUT:
outp(rp->port1, rp->data1);
if (rp->port2)
outp(rp->port2, rp->data2);
break;
}
}
}
/* Output a word to an I/O port. */
static void
out_word(unsigned int p,unsigned int d)
{
outp(p, d & 0xff);
outp(p + 1, (d >> 8) & 0xff);
}
/* Values for the data rotate register to implement drawing modes. */
static unsigned char mode_table[MODE_MAX + 1] = {
0x00, 0x18, 0x10, 0x08
};
/* Set the drawing mode.
* This is either SET, OR, AND, or XOR.
*/
static void
setmode(MODE mode)
{
if (mode > MODE_MAX)
return;
outp(GRREG, DATA_ROTATE);
outp(GRVAL, mode_table[mode]);
}
#if VGA_ET4000
/* VGA 800x600 16-color graphics (BIOS mode 0x29).
*/
REGIO graphics_on[] = {
/* Reset attr F/F */
IN, ATTRREG, 0, 0, 0,
/* Disable palette */
OUT, PALREG, 0, 0, 0,
/* Reset sequencer regs */
OUT, SEQREG, 0, SEQVAL, 0,
OUT, SEQREG, 1, SEQVAL, 1,
OUT, SEQREG, 2, SEQVAL, 0x0f,
OUT, SEQREG, 3, SEQVAL, 0,
OUT, SEQREG, 4, SEQVAL, 6,
/* Misc out reg */
OUT, GENREG1, 0xe3, 0, 0,
/* Sequencer enable */
OUT, SEQREG, 0, SEQVAL, 0x03,
/* Unprotect crtc regs 0-7 */
OUT, CRTCREG, 0x11, CRTCVAL, 0,
/* Crtc */
OUT, CRTCREG, 0, CRTCVAL, 0x7a,
OUT, CRTCREG, 1, CRTCVAL, 0x63,
OUT, CRTCREG, 2, CRTCVAL, 0x64,
OUT, CRTCREG, 3, CRTCVAL, 0x1d,
OUT, CRTCREG, 4, CRTCVAL, 0x68,
OUT, CRTCREG, 5, CRTCVAL, 0x9a,
OUT, CRTCREG, 6, CRTCVAL, 0x78,
OUT, CRTCREG, 7, CRTCVAL, 0xf0,
OUT, CRTCREG, 8, CRTCVAL, 0x00,
OUT, CRTCREG, 9, CRTCVAL, 0x60,
OUT, CRTCREG, 10, CRTCVAL, 0x00,
OUT, CRTCREG, 11, CRTCVAL, 0x00,
OUT, CRTCREG, 12, CRTCVAL, 0x00,
OUT, CRTCREG, 13, CRTCVAL, 0x00,
OUT, CRTCREG, 14, CRTCVAL, 0x00,
OUT, CRTCREG, 15, CRTCVAL, 0x00,
OUT, CRTCREG, 16, CRTCVAL, 0x5c,
OUT, CRTCREG, 17, CRTCVAL, 0x8e,
OUT, CRTCREG, 18, CRTCVAL, 0x57,
OUT, CRTCREG, 19, CRTCVAL, 0x32,
OUT, CRTCREG, 20, CRTCVAL, 0x00,
OUT, CRTCREG, 21, CRTCVAL, 0x5b,
OUT, CRTCREG, 22, CRTCVAL, 0x75,
OUT, CRTCREG, 23, CRTCVAL, 0xc3,
OUT, CRTCREG, 24, CRTCVAL, 0xff,
/* Graphics controller */
OUT, GENREG2, 0x00, 0, 0,
OUT, GENREG3, 0x01, 0, 0,
OUT, GRREG, 0, GRVAL, 0x00,
OUT, GRREG, 1, GRVAL, 0x00,
OUT, GRREG, 2, GRVAL, 0x00,
OUT, GRREG, 3, GRVAL, 0x00,
OUT, GRREG, 4, GRVAL, 0x00,
OUT, GRREG, 5, GRVAL, 0x00,
OUT, GRREG, 6, GRVAL, 0x05,
OUT, GRREG, 7, GRVAL, 0x0f,
OUT, GRREG, 8, GRVAL, 0xff,
/* Reset attribute flip/flop */
IN, ATTRREG, 0, 0, 0,
/* Palette */
OUT, PALREG, 0, PALREG, 0x00,
OUT, PALREG, 1, PALREG, 0x01,
OUT, PALREG, 2, PALREG, 0x02,
OUT, PALREG, 3, PALREG, 0x03,
OUT, PALREG, 4, PALREG, 0x04,
OUT, PALREG, 5, PALREG, 0x05,
OUT, PALREG, 6, PALREG, 0x06,
OUT, PALREG, 7, PALREG, 0x07,
OUT, PALREG, 8, PALREG, 0x38,
OUT, PALREG, 9, PALREG, 0x39,
OUT, PALREG, 10, PALREG, 0x3a,
OUT, PALREG, 11, PALREG, 0x3b,
OUT, PALREG, 12, PALREG, 0x3c,
OUT, PALREG, 13, PALREG, 0x3d,
OUT, PALREG, 14, PALREG, 0x3e,
OUT, PALREG, 15, PALREG, 0x3f,
OUT, PALREG, 16, PALREG, 0x01,
OUT, PALREG, 17, PALREG, 0x00,
OUT, PALREG, 18, PALREG, 0x0f,
OUT, PALREG, 19, PALREG, 0x00,
/* Enable palette */
OUT, PALREG, 0x20, 0, 0,
/* End of table */
DONE, 0, 0, 0, 0
};
/* VGA 80x25 text (BIOS mode 3).
*/
static REGIO graph_off[] = {
/* Reset attr F/F */
IN, ATTRREG, 0, 0, 0,
/* Disable palette */
OUT, PALREG, 0, 0, 0,
/* Reset sequencer regs */
OUT, SEQREG, 0, SEQVAL, 1,
OUT, SEQREG, 1, SEQVAL, 1,
OUT, SEQREG, 2, SEQVAL, 3,
OUT, SEQREG, 3, SEQVAL, 0,
OUT, SEQREG, 4, SEQVAL, 2,
/* Misc out reg */
OUT, GENREG1, 0x63, 0, 0,
/* Sequencer enable */
OUT, SEQREG, 0, SEQVAL, 3,
/* Unprotect crtc regs 0-7 */
OUT, CRTCREG, 0x11, CRTCVAL, 0,
/* Crtc */
OUT, CRTCREG, 0, CRTCVAL, 0x5f, /* horiz total */
OUT, CRTCREG, 1, CRTCVAL, 0x4f, /* horiz end */
OUT, CRTCREG, 2, CRTCVAL, 0x50, /* horiz blank */
OUT, CRTCREG, 3, CRTCVAL, 0x82, /* end blank */
OUT, CRTCREG, 4, CRTCVAL, 0x55, /* horiz retrace */
OUT, CRTCREG, 5, CRTCVAL, 0x81, /* end retrace */
OUT, CRTCREG, 6, CRTCVAL, 0xbf, /* vert total */
OUT, CRTCREG, 7, CRTCVAL, 0x1f, /* overflows */
OUT, CRTCREG, 8, CRTCVAL, 0x00, /* row scan */
OUT, CRTCREG, 9, CRTCVAL, 0x4f, /* max scan line */
OUT, CRTCREG, 10, CRTCVAL, 0x00, /* cursor start */
OUT, CRTCREG, 11, CRTCVAL, 0x0f, /* cursor end */
OUT, CRTCREG, 12, CRTCVAL, 0x0e, /* start high addr */
OUT, CRTCREG, 13, CRTCVAL, 0xb0, /* low addr */
OUT, CRTCREG, 14, CRTCVAL, 0x16, /* cursor high */
OUT, CRTCREG, 15, CRTCVAL, 0x30, /* cursor low */
OUT, CRTCREG, 16, CRTCVAL, 0x9c, /* vert retrace */
OUT, CRTCREG, 17, CRTCVAL, 0x8e, /* retrace end */
OUT, CRTCREG, 18, CRTCVAL, 0x8f, /* vert end */
OUT, CRTCREG, 19, CRTCVAL, 0x28, /* offset */
OUT, CRTCREG, 20, CRTCVAL, 0x1f, /* underline */
OUT, CRTCREG, 21, CRTCVAL, 0x96, /* vert blank */
OUT, CRTCREG, 22, CRTCVAL, 0xb9, /* end blank */
OUT, CRTCREG, 23, CRTCVAL, 0xa3, /* crt mode */
OUT, CRTCREG, 24, CRTCVAL, 0xff, /* line compare */
/* Graphics controller */
OUT, GENREG2, 0x00, 0, 0,
OUT, GENREG3, 0x01, 0, 0,
OUT, GRREG, 0, GRVAL, 0x00,
OUT, GRREG, 1, GRVAL, 0x00,
OUT, GRREG, 2, GRVAL, 0x00,
OUT, GRREG, 3, GRVAL, 0x00,
OUT, GRREG, 4, GRVAL, 0x00,
OUT, GRREG, 5, GRVAL, 0x10,
OUT, GRREG, 6, GRVAL, 0x0e,
OUT, GRREG, 7, GRVAL, 0x00,
OUT, GRREG, 8, GRVAL, 0xff,
/* Reset attribute flip/flop */
IN, ATTRREG, 0, 0, 0,
/* Palette */
OUT, PALREG, 0, PALREG, 0x00,
OUT, PALREG, 1, PALREG, 0x01,
OUT, PALREG, 2, PALREG, 0x02,
OUT, PALREG, 3, PALREG, 0x03,
OUT, PALREG, 4, PALREG, 0x04,
OUT, PALREG, 5, PALREG, 0x05,
OUT, PALREG, 6, PALREG, 0x06,
OUT, PALREG, 7, PALREG, 0x07,
OUT, PALREG, 8, PALREG, 0x10,
OUT, PALREG, 9, PALREG, 0x11,
OUT, PALREG, 10, PALREG, 0x12,
OUT, PALREG, 11, PALREG, 0x13,
OUT, PALREG, 12, PALREG, 0x14,
OUT, PALREG, 13, PALREG, 0x15,
OUT, PALREG, 14, PALREG, 0x16,
OUT, PALREG, 15, PALREG, 0x17,
OUT, PALREG, 16, PALREG, 0x08,
OUT, PALREG, 17, PALREG, 0x00,
OUT, PALREG, 18, PALREG, 0x0f,
OUT, PALREG, 19, PALREG, 0x00,
/* Enable palette */
OUT, PALREG, 0x20, 0, 0,
/* End of table */
DONE, 0, 0, 0, 0
};
#endif
#if VGA_STANDARD
/* VGA 640x480 16-color graphics (BIOS mode 0x12).
*/
static REGIO graphics_on[] = {
/* Reset attr F/F */
{ IN, ATTRREG, 0, 0, 0 },
/* Disable palette */
{ OUT, PALREG, 0, 0, 0 },
/* Reset sequencer regs */
{ OUT, SEQREG, 0, SEQVAL, 0 },
{ OUT, SEQREG, 1, SEQVAL, 1 },
{ OUT, SEQREG, 2, SEQVAL, 0x0f },
{ OUT, SEQREG, 3, SEQVAL, 0 },
{ OUT, SEQREG, 4, SEQVAL, 6 },
/* Misc out reg */
{ OUT, GENREG1, 0xe3, 0, 0 },
/* Sequencer enable */
{ OUT, SEQREG, 0, SEQVAL, 0x03 },
/* Unprotect crtc regs 0-7 */
{ OUT, CRTCREG, 0x11, CRTCVAL, 0 },
/* Crtc */
{ OUT, CRTCREG, 0, CRTCVAL, 0x5f },
{ OUT, CRTCREG, 1, CRTCVAL, 0x4f },
{ OUT, CRTCREG, 2, CRTCVAL, 0x50 },
{ OUT, CRTCREG, 3, CRTCVAL, 0x82 },
{ OUT, CRTCREG, 4, CRTCVAL, 0x54 },
{ OUT, CRTCREG, 5, CRTCVAL, 0x80 },
{ OUT, CRTCREG, 6, CRTCVAL, 0x0b },
{ OUT, CRTCREG, 7, CRTCVAL, 0x3e },
{ OUT, CRTCREG, 8, CRTCVAL, 0x00 },
{ OUT, CRTCREG, 9, CRTCVAL, 0x40 },
{ OUT, CRTCREG, 10, CRTCVAL, 0x00 },
{ OUT, CRTCREG, 11, CRTCVAL, 0x00 },
{ OUT, CRTCREG, 12, CRTCVAL, 0x00 },
{ OUT, CRTCREG, 13, CRTCVAL, 0x00 },
{ OUT, CRTCREG, 14, CRTCVAL, 0x00 },
{ OUT, CRTCREG, 15, CRTCVAL, 0x59 },
{ OUT, CRTCREG, 16, CRTCVAL, 0xea },
{ OUT, CRTCREG, 17, CRTCVAL, 0x8c },
{ OUT, CRTCREG, 18, CRTCVAL, 0xdf },
{ OUT, CRTCREG, 19, CRTCVAL, 0x28 },
{ OUT, CRTCREG, 20, CRTCVAL, 0x00 },
{ OUT, CRTCREG, 21, CRTCVAL, 0xe7 },
{ OUT, CRTCREG, 22, CRTCVAL, 0x04 },
{ OUT, CRTCREG, 23, CRTCVAL, 0xe3 },
{ OUT, CRTCREG, 24, CRTCVAL, 0xff },
/* Graphics controller */
{ OUT, GENREG2, 0x00, 0, 0 },
{ OUT, GENREG3, 0x01, 0, 0 },
{ OUT, GRREG, 0, GRVAL, 0x00 },
{ OUT, GRREG, 1, GRVAL, 0x00 },
{ OUT, GRREG, 2, GRVAL, 0x00 },
{ OUT, GRREG, 3, GRVAL, 0x00 },
{ OUT, GRREG, 4, GRVAL, 0x00 },
{ OUT, GRREG, 5, GRVAL, 0x00 },
{ OUT, GRREG, 6, GRVAL, 0x05 },
{ OUT, GRREG, 7, GRVAL, 0x0f },
{ OUT, GRREG, 8, GRVAL, 0xff },
/* Reset attribute flip/flop */
{ IN, ATTRREG, 0, 0, 0 },
/* Palette */
{ OUT, PALREG, 0, PALREG, 0x00 },
{ OUT, PALREG, 1, PALREG, 0x01 },
{ OUT, PALREG, 2, PALREG, 0x02 },
{ OUT, PALREG, 3, PALREG, 0x03 },
{ OUT, PALREG, 4, PALREG, 0x04 },
{ OUT, PALREG, 5, PALREG, 0x05 },
{ OUT, PALREG, 6, PALREG, 0x06 },
{ OUT, PALREG, 7, PALREG, 0x07 },
{ OUT, PALREG, 8, PALREG, 0x38 },
{ OUT, PALREG, 9, PALREG, 0x39 },
{ OUT, PALREG, 10, PALREG, 0x3a },
{ OUT, PALREG, 11, PALREG, 0x3b },
{ OUT, PALREG, 12, PALREG, 0x3c },
{ OUT, PALREG, 13, PALREG, 0x3d },
{ OUT, PALREG, 14, PALREG, 0x3e },
{ OUT, PALREG, 15, PALREG, 0x3f },
{ OUT, PALREG, 16, PALREG, 0x01 },
{ OUT, PALREG, 17, PALREG, 0x00 },
{ OUT, PALREG, 18, PALREG, 0x0f },
{ OUT, PALREG, 19, PALREG, 0x00 },
/* Enable palette */
{ OUT, PALREG, 0x20, 0, 0 },
/* End of table */
{ DONE, 0, 0, 0, 0 }
};
/* VGA 80x25 text (BIOS mode 3).
*/
static REGIO graph_off[] = {
/* Reset attr F/F */
{ IN, ATTRREG, 0, 0, 0 },
/* Disable palette */
{ OUT, PALREG, 0, 0, 0 },
/* Reset sequencer regs */
{ OUT, SEQREG, 0, SEQVAL, 1 },
{ OUT, SEQREG, 1, SEQVAL, 1 },
{ OUT, SEQREG, 2, SEQVAL, 3 },
{ OUT, SEQREG, 3, SEQVAL, 0 },
{ OUT, SEQREG, 4, SEQVAL, 2 },
/* Misc out reg */
{ OUT, GENREG1, 0x63, 0, 0 },
/* Sequencer enable */
{ OUT, SEQREG, 0, SEQVAL, 3 },
/* Unprotect crtc regs 0-7 */
{ OUT, CRTCREG, 0x11, CRTCVAL, 0 },
/* Crtc */
{ OUT, CRTCREG, 0, CRTCVAL, 0x5f }, /* horiz total */
{ OUT, CRTCREG, 1, CRTCVAL, 0x4f }, /* horiz end */
{ OUT, CRTCREG, 2, CRTCVAL, 0x50 }, /* horiz blank */
{ OUT, CRTCREG, 3, CRTCVAL, 0x82 }, /* end blank */
{ OUT, CRTCREG, 4, CRTCVAL, 0x55 }, /* horiz retrace */
{ OUT, CRTCREG, 5, CRTCVAL, 0x81 }, /* end retrace */
{ OUT, CRTCREG, 6, CRTCVAL, 0xbf }, /* vert total */
{ OUT, CRTCREG, 7, CRTCVAL, 0x1f }, /* overflows */
{ OUT, CRTCREG, 8, CRTCVAL, 0x00 }, /* row scan */
{ OUT, CRTCREG, 9, CRTCVAL, 0x4f }, /* max scan line */
{ OUT, CRTCREG, 10, CRTCVAL, 0x00 }, /* cursor start */
{ OUT, CRTCREG, 11, CRTCVAL, 0x0f }, /* cursor end */
{ OUT, CRTCREG, 12, CRTCVAL, 0x0e }, /* start high addr */
{ OUT, CRTCREG, 13, CRTCVAL, 0xb0 }, /* low addr */
{ OUT, CRTCREG, 14, CRTCVAL, 0x16 }, /* cursor high */
{ OUT, CRTCREG, 15, CRTCVAL, 0x30 }, /* cursor low */
{ OUT, CRTCREG, 16, CRTCVAL, 0x9c }, /* vert retrace */
{ OUT, CRTCREG, 17, CRTCVAL, 0x8e }, /* retrace end */
{ OUT, CRTCREG, 18, CRTCVAL, 0x8f }, /* vert end */
{ OUT, CRTCREG, 19, CRTCVAL, 0x28 }, /* offset */
{ OUT, CRTCREG, 20, CRTCVAL, 0x1f }, /* underline */
{ OUT, CRTCREG, 21, CRTCVAL, 0x96 }, /* vert blank */
{ OUT, CRTCREG, 22, CRTCVAL, 0xb9 }, /* end blank */
{ OUT, CRTCREG, 23, CRTCVAL, 0xa3 }, /* crt mode */
{ OUT, CRTCREG, 24, CRTCVAL, 0xff }, /* line compare */
/* Graphics controller */
{ OUT, GENREG2, 0x00, 0, 0 },
{ OUT, GENREG3, 0x01, 0, 0 },
{ OUT, GRREG, 0, GRVAL, 0x00 },
{ OUT, GRREG, 1, GRVAL, 0x00 },
{ OUT, GRREG, 2, GRVAL, 0x00 },
{ OUT, GRREG, 3, GRVAL, 0x00 },
{ OUT, GRREG, 4, GRVAL, 0x00 },
{ OUT, GRREG, 5, GRVAL, 0x10 },
{ OUT, GRREG, 6, GRVAL, 0x0e },
{ OUT, GRREG, 7, GRVAL, 0x00 },
{ OUT, GRREG, 8, GRVAL, 0xff },
/* Reset attribute flip/flop */
{ IN, ATTRREG, 0, 0, 0 },
/* Palette */
{ OUT, PALREG, 0, PALREG, 0x00 },
{ OUT, PALREG, 1, PALREG, 0x01 },
{ OUT, PALREG, 2, PALREG, 0x02 },
{ OUT, PALREG, 3, PALREG, 0x03 },
{ OUT, PALREG, 4, PALREG, 0x04 },
{ OUT, PALREG, 5, PALREG, 0x05 },
{ OUT, PALREG, 6, PALREG, 0x06 },
{ OUT, PALREG, 7, PALREG, 0x07 },
{ OUT, PALREG, 8, PALREG, 0x10 },
{ OUT, PALREG, 9, PALREG, 0x11 },
{ OUT, PALREG, 10, PALREG, 0x12 },
{ OUT, PALREG, 11, PALREG, 0x13 },
{ OUT, PALREG, 12, PALREG, 0x14 },
{ OUT, PALREG, 13, PALREG, 0x15 },
{ OUT, PALREG, 14, PALREG, 0x16 },
{ OUT, PALREG, 15, PALREG, 0x17 },
{ OUT, PALREG, 16, PALREG, 0x08 },
{ OUT, PALREG, 17, PALREG, 0x00 },
{ OUT, PALREG, 18, PALREG, 0x0f },
{ OUT, PALREG, 19, PALREG, 0x00 },
/* Enable palette */
{ OUT, PALREG, 0x20, 0, 0 },
/* End of table */
{ DONE, 0, 0, 0, 0 }
};
#endif
#if EGA_STANDARD
/* EGA 640x350 16-color graphics (BIOS mode 0x10).
*/
static REGIO graphics_on[] = {
/* Reset attr F/F */
IN, ATTRREG, 0, 0, 0,
/* Disable palette */
OUT, PALREG, 0, 0, 0,
/* Reset sequencer regs */
OUT, SEQREG, 0, SEQVAL, 0,
OUT, SEQREG, 1, SEQVAL, 1,
OUT, SEQREG, 2, SEQVAL, 0x0f,
OUT, SEQREG, 3, SEQVAL, 0,
OUT, SEQREG, 4, SEQVAL, 6,
/* Misc out reg */
OUT, GENREG1, 0xa7, 0, 0,
/* Sequencer enable */
OUT, SEQREG, 0, SEQVAL, 0x03,
/* Unprotect crtc regs 0-7 */
OUT, CRTCREG, 0x11, CRTCVAL, 0,
/* Crtc */
OUT, CRTCREG, 0, CRTCVAL, 0x5b,
OUT, CRTCREG, 1, CRTCVAL, 0x4f,
OUT, CRTCREG, 2, CRTCVAL, 0x53,
OUT, CRTCREG, 3, CRTCVAL, 0x37,
OUT, CRTCREG, 4, CRTCVAL, 0x52,
OUT, CRTCREG, 5, CRTCVAL, 0x00,
OUT, CRTCREG, 6, CRTCVAL, 0x6c,
OUT, CRTCREG, 7, CRTCVAL, 0x1f,
OUT, CRTCREG, 8, CRTCVAL, 0x00,
OUT, CRTCREG, 9, CRTCVAL, 0x00,
OUT, CRTCREG, 10, CRTCVAL, 0x00,
OUT, CRTCREG, 11, CRTCVAL, 0x00,
OUT, CRTCREG, 12, CRTCVAL, 0x00,
OUT, CRTCREG, 13, CRTCVAL, 0x00,
OUT, CRTCREG, 14, CRTCVAL, 0x00,
OUT, CRTCREG, 15, CRTCVAL, 0x00,
OUT, CRTCREG, 16, CRTCVAL, 0x5e,
OUT, CRTCREG, 17, CRTCVAL, 0x2b,
OUT, CRTCREG, 18, CRTCVAL, 0x5d,
OUT, CRTCREG, 19, CRTCVAL, 0x28,
OUT, CRTCREG, 20, CRTCVAL, 0x0f,
OUT, CRTCREG, 21, CRTCVAL, 0x5f,
OUT, CRTCREG, 22, CRTCVAL, 0x0a,
OUT, CRTCREG, 23, CRTCVAL, 0xe3,
OUT, CRTCREG, 24, CRTCVAL, 0xff,
/* Graphics controller */
OUT, GENREG2, 0x00, 0, 0,
OUT, GENREG3, 0x01, 0, 0,
OUT, GRREG, 0, GRVAL, 0x00,
OUT, GRREG, 1, GRVAL, 0x00,
OUT, GRREG, 2, GRVAL, 0x00,
OUT, GRREG, 3, GRVAL, 0x00,
OUT, GRREG, 4, GRVAL, 0x00,
OUT, GRREG, 5, GRVAL, 0x00,
OUT, GRREG, 6, GRVAL, 0x05,
OUT, GRREG, 7, GRVAL, 0x0f,
OUT, GRREG, 8, GRVAL, 0xff,
/* Reset attribute flip/flop */
IN, ATTRREG, 0, 0, 0,
/* Palette */
OUT, PALREG, 0, PALREG, 0x00,
OUT, PALREG, 1, PALREG, 0x01,
OUT, PALREG, 2, PALREG, 0x02,
OUT, PALREG, 3, PALREG, 0x03,
OUT, PALREG, 4, PALREG, 0x04,
OUT, PALREG, 5, PALREG, 0x05,
OUT, PALREG, 6, PALREG, 0x06,
OUT, PALREG, 7, PALREG, 0x07,
OUT, PALREG, 8, PALREG, 0x38,
OUT, PALREG, 9, PALREG, 0x39,
OUT, PALREG, 10, PALREG, 0x3a,
OUT, PALREG, 11, PALREG, 0x3b,
OUT, PALREG, 12, PALREG, 0x3c,
OUT, PALREG, 13, PALREG, 0x3d,
OUT, PALREG, 14, PALREG, 0x3e,
OUT, PALREG, 15, PALREG, 0x3f,
OUT, PALREG, 16, PALREG, 0x01,
OUT, PALREG, 17, PALREG, 0x00,
OUT, PALREG, 18, PALREG, 0x0f,
OUT, PALREG, 19, PALREG, 0x00,
/* Enable palette */
OUT, PALREG, 0x20, 0, 0,
/* End of table */
DONE, 0, 0, 0, 0
};
/* EGA 80x25 text (BIOS mode 3).
*/
static REGIO graph_off[] = {
/* Reset attr F/F */
IN, ATTRREG, 0, 0, 0,
/* Disable palette */
OUT, PALREG, 0, 0, 0,
/* Reset sequencer regs */
OUT, SEQREG, 0, SEQVAL, 1,
OUT, SEQREG, 1, SEQVAL, 1,
OUT, SEQREG, 2, SEQVAL, 3,
OUT, SEQREG, 3, SEQVAL, 0,
OUT, SEQREG, 4, SEQVAL, 3,
/* Misc out reg */
OUT, GENREG1, 0xa7, 0, 0,
/* Sequencer enable */
OUT, SEQREG, 0, SEQVAL, 3,
/* Crtc */
OUT, CRTCREG, 0, CRTCVAL, 0x5b, /* horiz total */
OUT, CRTCREG, 1, CRTCVAL, 0x4f, /* horiz end */
OUT, CRTCREG, 2, CRTCVAL, 0x53, /* horiz blank */
OUT, CRTCREG, 3, CRTCVAL, 0x37, /* end blank */
OUT, CRTCREG, 4, CRTCVAL, 0x51, /* horiz retrace */
OUT, CRTCREG, 5, CRTCVAL, 0x5b, /* end retrace */
OUT, CRTCREG, 6, CRTCVAL, 0x6c, /* vert total */
OUT, CRTCREG, 7, CRTCVAL, 0x1f, /* overflows */
OUT, CRTCREG, 8, CRTCVAL, 0x00, /* row scan */
OUT, CRTCREG, 9, CRTCVAL, 0x0d, /* max scan line */
OUT, CRTCREG, 10, CRTCVAL, 0x00, /* cursor start */
OUT, CRTCREG, 11, CRTCVAL, 0x0f, /* cursor end */
OUT, CRTCREG, 12, CRTCVAL, 0x00, /* start high addr */
OUT, CRTCREG, 13, CRTCVAL, 0x00, /* low addr */
OUT, CRTCREG, 14, CRTCVAL, 0x00, /* cursor high */
OUT, CRTCREG, 15, CRTCVAL, 0x00, /* cursor low */
OUT, CRTCREG, 16, CRTCVAL, 0x5e, /* vert retrace */
OUT, CRTCREG, 17, CRTCVAL, 0x2b, /* retrace end */
OUT, CRTCREG, 18, CRTCVAL, 0x5d, /* vert end */
OUT, CRTCREG, 19, CRTCVAL, 0x28, /* offset */
OUT, CRTCREG, 20, CRTCVAL, 0x0f, /* underline */
OUT, CRTCREG, 21, CRTCVAL, 0x5e, /* vert blank */
OUT, CRTCREG, 22, CRTCVAL, 0x0a, /* end blank */
OUT, CRTCREG, 23, CRTCVAL, 0xa3, /* crt mode */
OUT, CRTCREG, 24, CRTCVAL, 0xff, /* line compare */
/* Graphics controller */
OUT, GENREG2, 0x00, 0, 0,
OUT, GENREG3, 0x01, 0, 0,
OUT, GRREG, 0, GRVAL, 0x00,
OUT, GRREG, 1, GRVAL, 0x00,
OUT, GRREG, 2, GRVAL, 0x00,
OUT, GRREG, 3, GRVAL, 0x00,
OUT, GRREG, 4, GRVAL, 0x00,
OUT, GRREG, 5, GRVAL, 0x10,
OUT, GRREG, 6, GRVAL, 0x0e,
OUT, GRREG, 7, GRVAL, 0x00,
OUT, GRREG, 8, GRVAL, 0xff,
/* Reset attribute flip/flop */
IN, ATTRREG, 0, 0, 0,
/* Palette */
OUT, PALREG, 0, PALREG, 0x00,
OUT, PALREG, 1, PALREG, 0x01,
OUT, PALREG, 2, PALREG, 0x02,
OUT, PALREG, 3, PALREG, 0x03,
OUT, PALREG, 4, PALREG, 0x04,
OUT, PALREG, 5, PALREG, 0x05,
OUT, PALREG, 6, PALREG, 0x14,
OUT, PALREG, 7, PALREG, 0x07,
OUT, PALREG, 8, PALREG, 0x38,
OUT, PALREG, 9, PALREG, 0x39,
OUT, PALREG, 10, PALREG, 0x3a,
OUT, PALREG, 11, PALREG, 0x3b,
OUT, PALREG, 12, PALREG, 0x3c,
OUT, PALREG, 13, PALREG, 0x3d,
OUT, PALREG, 14, PALREG, 0x3e,
OUT, PALREG, 15, PALREG, 0x3f,
OUT, PALREG, 16, PALREG, 0x08,
OUT, PALREG, 17, PALREG, 0x00,
OUT, PALREG, 18, PALREG, 0x0f,
OUT, PALREG, 19, PALREG, 0x00,
/* Enable palette */
OUT, PALREG, 0x20, 0, 0,
/* End of table */
DONE, 0, 0, 0, 0
};
#endif

View File

@@ -1,48 +0,0 @@
/*
* videoAsm.S - This file contains code for displaying cursor on the console
*
* Copyright (C) 1998 valette@crf.canon.fr
*
* This code is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This code 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
.file "videoAsm.s"
#include <crt.h>
.text
.align 4
.globl wr_cursor /* Move cursor position */
/*
* void wr_cursor(newPosition, ioBaseAddr)
*/
wr_cursor: pushl %ecx
movl 8(%esp), %ecx /* Get new cursor position */
movb $CC_CURSHIGH, %al /* Cursor high location */
movl 12(%esp), %edx /* Get IO base address */
outb (%dx)
incw %dx /* Program Data register */
movb %ch, %al
outb (%dx) /* Update high location cursor */
decw %dx /* Program Index Register */
movb $CC_CURSLOW, %al /* Cursor low location */
outb (%dx)
incw %dx /* Program Data Register */
movb %cl, %al
outb (%dx) /* Update low location cursor */
popl %ecx
ret

View File

@@ -1,348 +0,0 @@
/*
* linux/drivers/char/vt.c
*
* Copyright (C) 1992 obz under the linux copyright
*
* Dynamic diacritical handling - aeb@cwi.nl - Dec 1993
* Dynamic keymap and string allocation - aeb@cwi.nl - May 1994
* Restrict VT switching via ioctl() - grif@cs.ucr.edu - Dec 1995
* Some code moved for less code duplication - Andi Kleen - Mar 1997
*
*
* by: Rosimildo da Silva --
* Ported to RTEMS to provide the basic interface to the console
* driver. Removed all stuff not required, such as VT_, Fonts, etc.
*/
#include <string.h> /* memcpy */
#include <sys/types.h>
#include <errno.h>
#include <bsp.h>
#include <i386_io.h>
#include <rtems.h>
#include <rtems/kd.h>
#include <rtems/keyboard.h>
/*
* Console (vt and kd) routines, as defined by USL SVR4 manual, and by
* experimentation and study of X386 SYSV handling.
*
* One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and
* /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console,
* and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will
* always treat our set of vt as numbered 1..MAX_NR_CONSOLES (corresponding to
* ttys 0..MAX_NR_CONSOLES-1). Explicitly naming VT 0 is illegal, but using
* /dev/tty0 (fg_console) as a target is legal, since an implicit aliasing
* to the current console is done by the main ioctl code.
*/
struct vt_struct *vt_cons[MAX_NR_CONSOLES];
/* Keyboard type: Default is KB_101, but can be set by machine
* specific code.
*/
unsigned char keyboard_type = KB_101;
/*
* Generates sound of some frequency for some number of clock ticks
*
* If freq is 0, will turn off sound, else will turn it on for that time.
* If msec is 0, will return immediately, else will sleep for msec time, then
* turn sound off.
*
* We also return immediately, which is what was implied within the X
* comments - KDMKTONE doesn't put the process to sleep.
*/
#if defined(__i386__) || defined(__alpha__) || defined(__powerpc__) \
|| (defined(__mips__) && !defined(CONFIG_SGI))
static void
kd_nosound(unsigned long ignored)
{
/* disable counter 2 */
outb(inb_p(0x61)&0xFC, 0x61);
return;
}
static void
_kd_mksound(unsigned int hz, unsigned int ticks)
{
unsigned int count = 0;
rtems_interrupt_lock_context lock_context;
if (hz > 20 && hz < 32767)
count = 1193180 / hz;
rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context);
/* del_timer(&sound_timer); */
if (count) {
/* enable counter 2 */
outb_p(inb_p(0x61)|3, 0x61);
/* set command for counter 2, 2 byte write */
outb_p(0xB6, TIMER_MODE);
/* select desired HZ */
outb_p(count & 0xff, TIMER_CNTR2);
outb((count >> 8) & 0xff, TIMER_CNTR2);
/*
if (ticks) {
sound_timer.expires = jiffies+ticks;
add_timer(&sound_timer);
}
*/
} else
kd_nosound(0);
rtems_interrupt_lock_release(&rtems_i386_i8254_access_lock, &lock_context);
return;
}
#else
void
_kd_mksound(unsigned int hz, unsigned int ticks)
{
}
#endif
void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound;
#define i (tmp.kb_index)
#define s (tmp.kb_table)
#define v (tmp.kb_value)
static inline int
do_kdsk_ioctl(int cmd, struct kbentry *user_kbe, int perm, struct kbd_struct *kbd)
{
struct kbentry tmp;
ushort *key_map, val;
tmp = *user_kbe;
if (i >= NR_KEYS) /* s cannot be >= MAX_NR_KEYMAPS */
return -EINVAL;
switch (cmd) {
case KDGKBENT:
key_map = key_maps[s];
if (key_map) {
val = U(key_map[i]);
if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
val = K_HOLE;
} else
val = (i ? K_HOLE : K_NOSUCHMAP);
user_kbe->kb_value = val;
return 0;
case KDSKBENT:
return -EINVAL;
}
return 0;
}
#undef i
#undef s
#undef v
#define HZ 100
static inline int
do_kbkeycode_ioctl(int cmd, struct kbkeycode *user_kbkc, int perm)
{
struct kbkeycode tmp;
int kc = 0;
tmp = *user_kbkc;
switch (cmd) {
case KDGETKEYCODE:
kc = getkeycode(tmp.scancode);
if (kc >= 0)
user_kbkc->keycode = kc;
break;
case KDSETKEYCODE:
if (!perm)
return -EPERM;
kc = setkeycode(tmp.scancode, tmp.keycode);
break;
}
return kc;
}
static inline int
do_kdgkb_ioctl(int cmd, struct kbsentry *user_kdgkb, int perm)
{
return -EINVAL;
}
/*
* We handle the console-specific ioctl's here. We allow the
* capability to modify any console, not just the fg_console.
*/
int vt_ioctl( unsigned int cmd, unsigned long arg)
{
int perm;
unsigned int console;
unsigned char ucval;
struct kbd_struct * kbd;
console = 0;
/*
* To have permissions to do most of the vt ioctls, we either have
* to be the owner of the tty, or super-user.
*/
perm = 1;
kbd = kbd_table + console;
switch (cmd) {
case KIOCSOUND:
if (!perm)
return -EPERM;
if (arg)
arg = 1193180 / arg;
kd_mksound(arg, 0);
return 0;
case KDMKTONE:
if (!perm)
return -EPERM;
{
unsigned int ticks, count;
/*
* Generate the tone for the appropriate number of ticks.
* If the time is zero, turn off sound ourselves.
*/
ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
count = ticks ? (arg & 0xffff) : 0;
if (count)
count = 1193180 / count;
kd_mksound(count, ticks);
return 0;
}
case KDGKBTYPE:
/*
* this is naive.
*/
ucval = keyboard_type;
goto setchar;
case KDSETMODE:
case KDGETMODE:
return -EINVAL;
case KDSKBMODE:
if (!perm)
return -EPERM;
switch(arg) {
case K_RAW:
kbd->kbdmode = VC_RAW;
break;
case K_MEDIUMRAW:
kbd->kbdmode = VC_MEDIUMRAW;
break;
case K_XLATE:
kbd->kbdmode = VC_XLATE;
compute_shiftstate();
break;
case K_UNICODE:
kbd->kbdmode = VC_UNICODE;
compute_shiftstate();
break;
default:
return -EINVAL;
}
return 0;
case KDGKBMODE:
ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW :
(kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW :
(kbd->kbdmode == VC_UNICODE) ? K_UNICODE :
K_XLATE);
goto setint;
/* this could be folded into KDSKBMODE, but for compatibility
reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
case KDSKBMETA:
switch(arg) {
case K_METABIT:
clr_vc_kbd_mode(kbd, VC_META);
break;
case K_ESCPREFIX:
set_vc_kbd_mode(kbd, VC_META);
break;
default:
return -EINVAL;
}
return 0;
case KDGKBMETA:
ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT);
setint:
*(int *)arg = ucval;
return 0;
case KDGETKEYCODE:
case KDSETKEYCODE:
return do_kbkeycode_ioctl(cmd, (struct kbkeycode *)arg, perm);
case KDGKBENT:
case KDSKBENT:
return do_kdsk_ioctl(cmd, (struct kbentry *)arg, perm, kbd);
case KDGKBDIACR:
{
struct kbdiacrs *a = (struct kbdiacrs *)arg;
a->kb_cnt = accent_table_size;
memcpy( a->kbdiacr, accent_table, accent_table_size*sizeof(struct kbdiacr) );
return 0;
}
case KDSKBDIACR:
{
struct kbdiacrs *a = (struct kbdiacrs *)arg;
unsigned int ct;
if (!perm)
return -EPERM;
ct = a->kb_cnt;
if (ct >= MAX_DIACR)
return -EINVAL;
accent_table_size = ct;
memcpy(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr));
return 0;
}
/* the ioctls below read/set the flags usually shown in the leds */
/* don't use them - they will go away without warning */
case KDGKBLED:
ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
goto setchar;
case KDSKBLED:
if (!perm)
return -EPERM;
if (arg & ~0x77)
return -EINVAL;
kbd->ledflagstate = (arg & 7);
kbd->default_ledflagstate = ((arg >> 4) & 7);
set_leds();
return 0;
/* the ioctls below only set the lights, not the functions */
/* for those, see KDGKBLED and KDSKBLED above */
case KDGETLED:
ucval = getledstate();
setchar:
*(char*)arg = ucval;
return 0;
case KDSETLED:
if (!perm)
return -EPERM;
setledstate(kbd, arg);
return 0;
default:
return -EINVAL;
}
}

View File

@@ -30,8 +30,8 @@ librtemsbsp_a_SOURCES += ../shared/startup/bspreset.c
# clock
librtemsbsp_a_SOURCES +=../../../../../../bsps/lm32/shared/clock/ckinit.c
# console
librtemsbsp_a_SOURCES += ../shared/console/console.c
librtemsbsp_a_SOURCES += ../shared/console/uart.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/lm32/shared/console/console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/lm32/shared/console/uart.c
# timer
librtemsbsp_a_SOURCES += ../shared/timer/timer.c

View File

@@ -1,178 +0,0 @@
/*
* Console driver for Lattice Mico32 (lm32).
*/
/*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*/
#define NO_BSP_INIT
#include <bsp.h>
#include <rtems/bspIo.h>
#include <rtems/libio.h>
#include <rtems/console.h>
/* console_initialize
*
* This routine initializes the console IO driver.
*/
rtems_device_driver console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code status;
printk("console_initialize\n");
status = rtems_io_register_name(
"/dev/console",
major,
(rtems_device_minor_number) 0
);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred(status);
return RTEMS_SUCCESSFUL;
}
/* inbyte
*
* This routine reads a character from the SOURCE.
*/
static int inbyte( void )
{
/*
* If polling, wait until a character is available.
*/
return BSP_uart_polled_read();
}
/* outbyte
*
* This routine transmits a character out the SOURCE. It may support
* XON/XOFF flow control.
*/
static void outbyte(
char ch
)
{
/*
* If polling, wait for the transmitter to be ready.
* Check for flow control requests and process.
* Then output the character.
*/
BSP_uart_polled_write(ch);
}
/*
* Open entry point
*/
rtems_device_driver console_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return RTEMS_SUCCESSFUL;
}
/*
* Close entry point
*/
rtems_device_driver console_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return RTEMS_SUCCESSFUL;
}
/*
* read bytes from the serial port. We only have stdin.
*/
rtems_device_driver console_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
rtems_libio_rw_args_t *rw_args;
char *buffer;
int maximum;
int count = 0;
rw_args = (rtems_libio_rw_args_t *) arg;
buffer = rw_args->buffer;
maximum = rw_args->count;
for (count = 0; count < maximum; count++) {
buffer[ count ] = inbyte();
if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
buffer[ count++ ] = '\n';
break;
}
}
rw_args->bytes_moved = count;
return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
}
/*
* write bytes to the serial port. Stdout and stderr are the same.
*/
rtems_device_driver console_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
int count;
int maximum;
rtems_libio_rw_args_t *rw_args;
char *buffer;
rw_args = (rtems_libio_rw_args_t *) arg;
buffer = rw_args->buffer;
maximum = rw_args->count;
for (count = 0; count < maximum; count++) {
if ( buffer[ count ] == '\n') {
outbyte('\r');
}
outbyte( buffer[ count ] );
}
rw_args->bytes_moved = maximum;
return 0;
}
/*
* IO Control entry point
*/
rtems_device_driver console_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return RTEMS_SUCCESSFUL;
}
BSP_output_char_function_type BSP_output_char = BSP_uart_polled_write;
BSP_polling_getchar_function_type BSP_poll_char = BSP_uart_polled_read;

View File

@@ -1,73 +0,0 @@
/*
* Uart driver for Lattice Mico32 (lm32) UART
*/
/*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*/
#include "../include/system_conf.h"
#include "uart.h"
#include <bsp.h>
#include <rtems/libio.h>
static inline int uartread(unsigned int reg)
{
return *((int*)(UART_BASE_ADDRESS + reg));
}
static inline void uartwrite(unsigned int reg, int value)
{
*((int*)(UART_BASE_ADDRESS + reg)) = value;
}
void BSP_uart_init(int baud)
{
/* Disable UART interrupts */
uartwrite(LM32_UART_IER, 0);
/* Line control 8 bit, 1 stop, no parity */
uartwrite(LM32_UART_LCR, LM32_UART_LCR_8BIT);
/* Modem control, DTR = 1, RTS = 1 */
uartwrite(LM32_UART_MCR, LM32_UART_MCR_DTR | LM32_UART_MCR_RTS);
/* Set baud rate */
uartwrite(LM32_UART_DIV, CPU_FREQUENCY/baud);
}
void BSP_uart_polled_write(char ch)
{
/* Insert CR before LF */
if (ch == '\n')
BSP_uart_polled_write('\r');
/* Wait until THR is empty. */
while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_THRE));
uartwrite(LM32_UART_RBR, ch);
}
int BSP_uart_polled_read( void )
{
/* Wait until there is a byte in RBR */
while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_DR));
return (int) uartread(LM32_UART_RBR);
}
char BSP_uart_is_character_ready(char *ch)
{
if (uartread(LM32_UART_LSR) & LM32_UART_LSR_DR)
{
*ch = (char) uartread(LM32_UART_RBR);
return true;
}
*ch = '0';
return false;
}

View File

@@ -1,102 +0,0 @@
/**
* @file
* @ingroup lm32_shared lm32_uart
* @brief LatticeMico32 UART definitions
*/
/*
* This file contains definitions for LatticeMico32 UART
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*/
/**
* @defgroup lm32_uart LM32 UART
* @ingroup lm32_shared
* @brief LatticeMico32 UART definitions
* @{
*/
#ifndef _BSPUART_H
#define _BSPUART_H
void BSP_uart_init(int baud);
/* Receive buffer register / transmit holding register */
#define LM32_UART_RBR (0x0000)
/* Interrupt enable register */
#define LM32_UART_IER (0x0004)
#define LM32_UART_IER_RBRI (0x0001)
#define LM32_UART_IER_THRI (0x0002)
#define LM32_UART_IER_RLSI (0x0004)
#define LM32_UART_IER_MSI (0x0008)
/* Interrupt identification register */
#define LM32_UART_IIR (0x0008)
#define LM32_UART_IIR_STAT (0x0001)
#define LM32_UART_IIR_ID0 (0x0002)
#define LM32_UART_IIR_ID1 (0x0004)
/* Line control register */
#define LM32_UART_LCR (0x000C)
#define LM32_UART_LCR_WLS0 (0x0001)
#define LM32_UART_LCR_WLS1 (0x0002)
#define LM32_UART_LCR_STB (0x0004)
#define LM32_UART_LCR_PEN (0x0008)
#define LM32_UART_LCR_EPS (0x0010)
#define LM32_UART_LCR_SP (0x0020)
#define LM32_UART_LCR_SB (0x0040)
#define LM32_UART_LCR_5BIT (0)
#define LM32_UART_LCR_6BIT (LM32_UART_LCR_WLS0)
#define LM32_UART_LCR_7BIT (LM32_UART_LCR_WLS1)
#define LM32_UART_LCR_8BIT (LM32_UART_LCR_WLS1 | LM32_UART_LCR_WLS0)
/* Modem control register */
#define LM32_UART_MCR (0x0010)
#define LM32_UART_MCR_DTR (0x0001)
#define LM32_UART_MCR_RTS (0x0002)
/* Line status register */
#define LM32_UART_LSR (0x0014)
#define LM32_UART_LSR_DR (0x0001)
#define LM32_UART_LSR_OE (0x0002)
#define LM32_UART_LSR_PE (0x0004)
#define LM32_UART_LSR_FE (0x0008)
#define LM32_UART_LSR_BI (0x0010)
#define LM32_UART_LSR_THRE (0x0020)
#define LM32_UART_LSR_TEMT (0x0040)
/* Modem status register */
#define LM32_UART_MSR (0x0018)
#define LM32_UART_MSR_DCTS (0x0001)
#define LM32_UART_MSR_DDSR (0x0002)
#define LM32_UART_MSR_TERI (0x0004)
#define LM32_UART_MSR_DDCD (0x0008)
#define LM32_UART_MSR_CTS (0x0010)
#define LM32_UART_MSR_DSR (0x0020)
#define LM32_UART_MSR_RI (0x0040)
#define LM32_UART_MSR_DCD (0x0000)
/* Baud-rate divisor register */
#define LM32_UART_DIV (0x001C)
#endif /* _BSPUART_H */
/** @} */

Some files were not shown because too many files have changed in this diff Show More