From 8fdecf6c5589493d3559a79cdd9b752c9065f140 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 15 Jun 2023 13:24:28 +0200 Subject: bsps: Use new APBUART register block API --- bsps/include/grlib/apbuart_termios.h | 4 +- bsps/riscv/griscv/console/console.c | 2 +- bsps/riscv/griscv/console/printk_support.c | 23 +++-- bsps/shared/grlib/uart/apbuart_cons.c | 136 +++++++++++++++++------------ bsps/shared/grlib/uart/apbuart_polled.c | 52 ++++++----- bsps/shared/grlib/uart/apbuart_termios.c | 49 +++++++---- bsps/sparc/leon3/console/console.c | 2 +- bsps/sparc/leon3/console/printk_support.c | 16 ++-- bsps/sparc/leon3/include/bsp/leon3.h | 62 +++++++++++++ 9 files changed, 235 insertions(+), 111 deletions(-) create mode 100644 bsps/sparc/leon3/include/bsp/leon3.h diff --git a/bsps/include/grlib/apbuart_termios.h b/bsps/include/grlib/apbuart_termios.h index 82eb4b6de4..a19b99b609 100644 --- a/bsps/include/grlib/apbuart_termios.h +++ b/bsps/include/grlib/apbuart_termios.h @@ -34,7 +34,7 @@ #define APBUART_TERMIOS_H #include -#include "grlib.h" +#include "apbuart.h" #ifdef __cplusplus extern "C" { @@ -42,7 +42,7 @@ extern "C" { struct apbuart_context { rtems_termios_device_context base; - struct apbuart_regs *regs; + apbuart *regs; unsigned int freq_hz; rtems_vector_number irq; volatile int sending; diff --git a/bsps/riscv/griscv/console/console.c b/bsps/riscv/griscv/console/console.c index af4c19d4cb..0627be5ee3 100644 --- a/bsps/riscv/griscv/console/console.c +++ b/bsps/riscv/griscv/console/console.c @@ -82,7 +82,7 @@ static int find_matching_apbuart(struct ambapp_dev *dev, int index, void *arg) struct ambapp_apb_info *apb = (struct ambapp_apb_info *)dev->devinfo; /* Extract needed information of one APBUART */ - apbuarts[uarts].regs = (struct apbuart_regs *)apb->start; + apbuarts[uarts].regs = (apbuart *)apb->start; apbuarts[uarts].irq = apb->common.irq; /* Get APBUART core frequency, it is assumed that it is the same * as Bus frequency where the UART is situated diff --git a/bsps/riscv/griscv/console/printk_support.c b/bsps/riscv/griscv/console/printk_support.c index 3a3450551f..f3af16be4d 100644 --- a/bsps/riscv/griscv/console/printk_support.c +++ b/bsps/riscv/griscv/console/printk_support.c @@ -43,9 +43,10 @@ #include #include #include +#include int grlib_debug_uart_index __attribute__((weak)) = 0; -struct apbuart_regs *grlib_debug_uart = NULL; +apbuart *grlib_debug_uart = NULL; /* Before UART driver has registered (or when no UART is available), calls to * printk that gets to bsp_out_char() will be filling data into the @@ -87,13 +88,17 @@ static void bsp_debug_uart_init(void) VENDOR_GAISLER, GAISLER_APBUART, ambapp_find_by_idx, (void *)&i); if (adev) { + uint32_t ctrl; + /* Found a matching debug console, initialize debug uart if present * for printk */ apb = (struct ambapp_apb_info *)adev->devinfo; - grlib_debug_uart = (struct apbuart_regs *)apb->start; - grlib_debug_uart->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; - grlib_debug_uart->status = 0; + grlib_debug_uart = (apbuart *)apb->start; + ctrl = grlib_load_32(&grlib_debug_uart->ctrl); + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; + grlib_store_32(&grlib_debug_uart->ctrl, ctrl); + grlib_store_32(&grlib_debug_uart->status, 0); } } @@ -107,10 +112,14 @@ RTEMS_SYSINIT_ITEM( static void bsp_out_char(char c) { if (grlib_debug_uart == NULL) { + uint32_t ctrl; + /* Try to assign standard UART address to debug driver to pass some tests */ - grlib_debug_uart = (struct apbuart_regs *) 0x80000100; - grlib_debug_uart->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; - grlib_debug_uart->status = 0; + grlib_debug_uart = (apbuart *) 0x80000100; + ctrl = grlib_load_32(&grlib_debug_uart->ctrl); + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; + grlib_store_32(&grlib_debug_uart->ctrl, ctrl); + grlib_store_32(&grlib_debug_uart->status, 0); /* Local debug buffer when UART driver has not registered */ /* pre_printk_dbgbuf[pre_printk_pos++] = c; diff --git a/bsps/shared/grlib/uart/apbuart_cons.c b/bsps/shared/grlib/uart/apbuart_cons.c index 5d47b7f4a1..74f9bf3e0c 100644 --- a/bsps/shared/grlib/uart/apbuart_cons.c +++ b/bsps/shared/grlib/uart/apbuart_cons.c @@ -47,11 +47,15 @@ #include #include #include -#include +#include #include #include #include +#ifdef LEON3 +#include +#endif + /*#define DEBUG 1 */ #ifdef DEBUG @@ -60,12 +64,6 @@ #define DBG(x...) #endif -/* LEON3 Low level transmit/receive functions provided by debug-uart code */ -#ifdef LEON3 -#include -extern struct apbuart_regs *leon3_debug_uart; /* The debug UART */ -#endif - /* Probed hardware capabilities */ enum { CAP_FIFO = 0x01, /* FIFO available */ @@ -74,7 +72,7 @@ enum { struct apbuart_priv { struct console_dev condev; struct drvmgr_dev *dev; - struct apbuart_regs *regs; + apbuart *regs; struct rtems_termios_tty *tty; char devName[52]; volatile int sending; @@ -213,18 +211,23 @@ static const rtems_termios_device_handler handler_polled = { * can select appropriate routines for the hardware. probecap() return value * is a CAP_ bitmask. */ -static int probecap(struct apbuart_regs *regs) +static int probecap(apbuart *regs) { int cap = 0; + uint32_t ctrl; /* Probe FIFO */ - if (regs->ctrl & APBUART_CTRL_FA) { + ctrl = grlib_load_32(®s->ctrl); + if (ctrl & APBUART_CTRL_FA) { cap |= CAP_FIFO; /* Probe RX delayed interrupt */ - regs->ctrl |= APBUART_CTRL_DI; - if (regs->ctrl & APBUART_CTRL_DI) { - regs->ctrl &= ~APBUART_CTRL_DI; + ctrl |= APBUART_CTRL_DI; + grlib_store_32(®s->ctrl, ctrl); + ctrl = grlib_load_32(®s->ctrl); + if (ctrl & APBUART_CTRL_DI) { + ctrl &= ~APBUART_CTRL_DI; + grlib_store_32(®s->ctrl, ctrl); cap |= CAP_DI; } } @@ -241,6 +244,7 @@ int apbuart_init1(struct drvmgr_dev *dev) char prefix[32]; unsigned int db; static int first_uart = 1; + uint32_t ctrl; /* The default operation in AMP is to use APBUART[0] for CPU[0], * APBUART[1] for CPU[1] and so on. The remaining UARTs is not used @@ -269,10 +273,12 @@ int apbuart_init1(struct drvmgr_dev *dev) if (ambadev == NULL) return -1; pnpinfo = &ambadev->info; - priv->regs = (struct apbuart_regs *)pnpinfo->apb_slv->start; + priv->regs = (apbuart *)pnpinfo->apb_slv->start; /* Clear HW regs, leave baudrate register as it is */ - priv->regs->status = 0; + grlib_store_32(&priv->regs->status, 0); + + ctrl = grlib_load_32(&priv->regs->ctrl); /* leave Transmitter/receiver if this is the RTEMS debug UART (assume * it has been setup by boot loader). @@ -280,10 +286,10 @@ int apbuart_init1(struct drvmgr_dev *dev) db = 0; #ifdef LEON3 if (priv->regs == leon3_debug_uart) { - db = priv->regs->ctrl & (APBUART_CTRL_RE | - APBUART_CTRL_TE | - APBUART_CTRL_PE | - APBUART_CTRL_PS); + db = ctrl & (APBUART_CTRL_RE | + APBUART_CTRL_TE | + APBUART_CTRL_PE | + APBUART_CTRL_PS); } #endif /* Let UART debug tunnelling be untouched if Flow-control is set. @@ -293,12 +299,12 @@ int apbuart_init1(struct drvmgr_dev *dev) * guess that we are debugging if FL is already set, the debugger set * either LB or DB depending on UART capabilities. */ - if (priv->regs->ctrl & APBUART_CTRL_FL) { - db |= priv->regs->ctrl & (APBUART_CTRL_DB | + if (ctrl & APBUART_CTRL_FL) { + db |= ctrl & (APBUART_CTRL_DB | APBUART_CTRL_LB | APBUART_CTRL_FL); } - priv->regs->ctrl = db; + grlib_store_32(&priv->regs->ctrl, db); priv->cap = probecap(priv->regs); @@ -387,12 +393,13 @@ static int apbuart_info( sprintf(buf, "FS Name: %s", priv->condev.fsname); print_line(p, buf); } - sprintf(buf, "STATUS REG: 0x%x", priv->regs->status); + sprintf(buf, "STATUS REG: 0x%x", grlib_load_32(&priv->regs->status)); print_line(p, buf); - sprintf(buf, "CTRL REG: 0x%x", priv->regs->ctrl); + sprintf(buf, "CTRL REG: 0x%x", grlib_load_32(&priv->regs->ctrl)); print_line(p, buf); sprintf(buf, "SCALER REG: 0x%x baud rate %d", - priv->regs->scaler, apbuart_get_baud(priv)); + grlib_load_32(&priv->regs->scaler), + apbuart_get_baud(priv)); print_line(p, buf); return DRVMGR_OK; @@ -407,6 +414,8 @@ static bool first_open( ) { struct apbuart_priv *uart = base_get_priv(base); + apbuart *regs = uart->regs; + uint32_t ctrl; uart->tty = tty; @@ -418,7 +427,8 @@ static bool first_open( } /* Enable TX/RX */ - uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; + ctrl = grlib_load_32(®s->ctrl); + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; if (uart->mode != TERMIOS_POLLED) { int ret; @@ -435,15 +445,15 @@ static bool first_open( uart->sending = 0; /* Turn on RX interrupts */ - ctrl = uart->regs->ctrl; ctrl |= APBUART_CTRL_RI; if (uart->cap & CAP_DI) { /* Use RX FIFO interrupt only if delayed interrupt available. */ ctrl |= (APBUART_CTRL_DI | APBUART_CTRL_RF); } - uart->regs->ctrl = ctrl; } + grlib_store_32(®s->ctrl, ctrl); + return true; } @@ -454,13 +464,16 @@ static void last_close( ) { struct apbuart_priv *uart = base_get_priv(base); + apbuart *regs = uart->regs; rtems_interrupt_lock_context lock_context; + uint32_t ctrl; if (uart->mode != TERMIOS_POLLED) { /* Turn off RX interrupts */ rtems_termios_device_lock_acquire(base, &lock_context); - uart->regs->ctrl &= - ~(APBUART_CTRL_DI | APBUART_CTRL_RI | APBUART_CTRL_RF); + ctrl = grlib_load_32(®s->ctrl); + ctrl &= ~(APBUART_CTRL_DI | APBUART_CTRL_RI | APBUART_CTRL_RF); + grlib_store_32(®s->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); /**** Flush device ****/ @@ -468,8 +481,8 @@ static void last_close( /* Wait until all data has been sent */ } while ( - (uart->regs->ctrl & APBUART_CTRL_TE) && - !(uart->regs->status & APBUART_STATUS_TS) + (grlib_load_32(®s->ctrl) & APBUART_CTRL_TE) && + !(grlib_load_32(®s->status) & APBUART_STATUS_TS) ) { /* Wait until all data has left shift register */ } @@ -480,8 +493,11 @@ static void last_close( #ifdef LEON3 /* Disable TX/RX if not used for DEBUG */ - if (uart->regs != leon3_debug_uart) - uart->regs->ctrl &= ~(APBUART_CTRL_RE | APBUART_CTRL_TE); + if (regs != leon3_debug_uart) { + ctrl = grlib_load_32(®s->ctrl); + ctrl &= ~(APBUART_CTRL_RE | APBUART_CTRL_TE); + grlib_store_32(®s->ctrl, ctrl); + } #endif } @@ -497,10 +513,11 @@ static int read_task(rtems_termios_device_context *base) { rtems_interrupt_lock_context lock_context; struct apbuart_priv *uart = base_get_priv(base); - struct apbuart_regs *regs = uart->regs; + apbuart *regs = uart->regs; int cnt; char buf[33]; struct rtems_termios_tty *tty; + uint32_t ctrl; uint32_t ctrl_add; ctrl_add = APBUART_CTRL_RI; @@ -511,10 +528,10 @@ static int read_task(rtems_termios_device_context *base) do { cnt = 0; while ( - (regs->status & APBUART_STATUS_DR) && + (grlib_load_32(®s->status) & APBUART_STATUS_DR) && (cnt < sizeof(buf)) ) { - buf[cnt] = regs->data; + buf[cnt] = grlib_load_32(®s->data); cnt++; } if (0 < cnt) { @@ -528,9 +545,11 @@ static int read_task(rtems_termios_device_context *base) * afterwards. */ rtems_termios_device_lock_acquire(base, &lock_context); - regs->ctrl |= ctrl_add; + ctrl = grlib_load_32(®s->ctrl); + ctrl |= ctrl_add; + grlib_store_32(®s->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); - } while (regs->status & APBUART_STATUS_DR); + } while (grlib_load_32(®s->status) & APBUART_STATUS_DR); return EOF; } @@ -541,7 +560,7 @@ int apbuart_get_baud(struct apbuart_priv *uart) unsigned int scaler; /* Get current scaler setting */ - scaler = uart->regs->scaler; + scaler = grlib_load_32(&uart->regs->scaler); /* Get APBUART core frequency */ drvmgr_freq_get(uart->dev, DEV_APB_SLV, &core_clk_hz); @@ -576,7 +595,7 @@ static bool set_attributes( rtems_termios_device_lock_acquire(base, &lock_context); /* Read out current value */ - ctrl = uart->regs->ctrl; + ctrl = grlib_load_32(&uart->regs->ctrl); switch(t->c_cflag & (PARENB|PARODD)){ case (PARENB|PARODD): @@ -603,7 +622,7 @@ static bool set_attributes( ctrl &= ~APBUART_CTRL_FL; /* Update new settings */ - uart->regs->ctrl = ctrl; + grlib_store_32(&uart->regs->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); @@ -617,7 +636,7 @@ static bool set_attributes( scaler = (((core_clk_hz*10)/(baud*8))-5)/10; /* Set new baud rate by setting scaler */ - uart->regs->scaler = scaler; + grlib_store_32(&uart->regs->scaler, scaler); } return true; @@ -637,7 +656,7 @@ static void get_attributes( t->c_cflag |= CS8; /* Read out current parity */ - ctrl = uart->regs->ctrl; + ctrl = grlib_load_32(&uart->regs->ctrl); if (ctrl & APBUART_CTRL_PE) { if (ctrl & APBUART_CTRL_PS) t->c_cflag |= PARENB|PARODD; /* Odd parity */ @@ -673,11 +692,11 @@ static void write_interrupt( ) { struct apbuart_priv *uart = base_get_priv(base); - struct apbuart_regs *regs = uart->regs; + apbuart *regs = uart->regs; int sending; unsigned int ctrl; - ctrl = regs->ctrl; + ctrl = grlib_load_32(®s->ctrl); if (len > 0) { /* @@ -685,28 +704,30 @@ static void write_interrupt( * we can tell termios later. */ /* Enable TX interrupt (interrupt is edge-triggered) */ - regs->ctrl = ctrl | APBUART_CTRL_TI; + ctrl |= APBUART_CTRL_TI; + grlib_store_32(®s->ctrl, ctrl); if (ctrl & APBUART_CTRL_FA) { /* APBUART with FIFO.. Fill as many as FIFO allows */ sending = 0; while ( - ((regs->status & APBUART_STATUS_TF) == 0) && + ((grlib_load_32(®s->status) & APBUART_STATUS_TF) == 0) && (sending < len) ) { - regs->data = *buf; + grlib_store_32(®s->data, *buf); buf++; sending++; } } else { /* start UART TX, this will result in an interrupt when done */ - regs->data = *buf; + grlib_store_32(®s->data, *buf); sending = 1; } } else { /* No more to send, disable TX interrupts */ - regs->ctrl = ctrl & ~APBUART_CTRL_TI; + ctrl &= ~APBUART_CTRL_TI; + grlib_store_32(®s->ctrl, ctrl); /* Tell close that we sent everything */ sending = 0; @@ -722,21 +743,24 @@ static void apbuart_cons_isr(void *arg) rtems_termios_device_context *base; struct console_dev *condev = rtems_termios_get_device_context(tty); struct apbuart_priv *uart = condev_get_priv(condev); - struct apbuart_regs *regs = uart->regs; + apbuart *regs = uart->regs; unsigned int status; char buf[33]; int cnt; if (uart->mode == TERMIOS_TASK_DRIVEN) { - if ((status = regs->status) & APBUART_STATUS_DR) { + if ((status = grlib_load_32(®s->status)) & APBUART_STATUS_DR) { rtems_interrupt_lock_context lock_context; + uint32_t ctrl; /* Turn off RX interrupts */ base = rtems_termios_get_device_context(tty); rtems_termios_device_lock_acquire(base, &lock_context); - regs->ctrl &= + ctrl = grlib_load_32(®s->ctrl); + ctrl &= ~(APBUART_CTRL_DI | APBUART_CTRL_RI | APBUART_CTRL_RF); + grlib_store_32(®s->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); /* Activate termios RX daemon task */ rtems_termios_rxirq_occured(tty); @@ -749,10 +773,10 @@ static void apbuart_cons_isr(void *arg) */ cnt = 0; while ( - ((status=regs->status) & APBUART_STATUS_DR) && + ((status=grlib_load_32(®s->status)) & APBUART_STATUS_DR) && (cnt < sizeof(buf)) ) { - buf[cnt] = regs->data; + buf[cnt] = grlib_load_32(®s->data); cnt++; } if (0 < cnt) { diff --git a/bsps/shared/grlib/uart/apbuart_polled.c b/bsps/shared/grlib/uart/apbuart_polled.c index b83af56b09..f3e4997a12 100644 --- a/bsps/shared/grlib/uart/apbuart_polled.c +++ b/bsps/shared/grlib/uart/apbuart_polled.c @@ -1,8 +1,17 @@ /* SPDX-License-Identifier: BSD-2-Clause */ +/** + * @file + * + * @ingroup RTEMSDeviceGRLIBAPBUART + * + * @brief This source file contains the implementation of + * apbuart_outbyte_wait(), apbuart_outbyte_polled(), and + * apbuart_inbyte_nonblocking(). + */ + /* - * COPYRIGHT (c) 2010. - * Cobham Gaisler AB. + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,38 +36,37 @@ */ #include +#include -#include +#include -void apbuart_outbyte_wait(const struct apbuart_regs *regs) +void apbuart_outbyte_wait( const apbuart *regs ) { - while ( (regs->status & APBUART_STATUS_TE) == 0 ) { - /* Lower bus utilization while waiting for UART */ - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); + while ( ( grlib_load_32( ®s->status ) & APBUART_STATUS_TE ) == 0 ) { + _IO_Relax(); } } -void apbuart_outbyte_polled(struct apbuart_regs *regs, char ch) +void apbuart_outbyte_polled( apbuart *regs, char ch) { - apbuart_outbyte_wait(regs); - regs->data = (uint8_t) ch; + apbuart_outbyte_wait( regs ); + grlib_store_32( ®s->data, (uint8_t) ch ); } -int apbuart_inbyte_nonblocking(struct apbuart_regs *regs) +int apbuart_inbyte_nonblocking( apbuart *regs ) { - /* Clear errors */ - regs->status = ~APBUART_STATUS_ERR; + uint32_t status; + + status = grlib_load_32( ®s->status ); + + /* Clear errors, writes to non-error flags are ignored */ + status &= ~( APBUART_STATUS_FE | APBUART_STATUS_PE | APBUART_STATUS_OV | + APBUART_STATUS_BR ); + grlib_store_32( ®s->status, status ); - if ((regs->status & APBUART_STATUS_DR) == 0) { + if ( ( status & APBUART_STATUS_DR ) == 0 ) { return -1; } - return (uint8_t) regs->data; + return (int) APBUART_DATA_DATA_GET( grlib_load_32( ®s->data ) ); } diff --git a/bsps/shared/grlib/uart/apbuart_termios.c b/bsps/shared/grlib/uart/apbuart_termios.c index 6506b70e3d..8b5ccd67f6 100644 --- a/bsps/shared/grlib/uart/apbuart_termios.c +++ b/bsps/shared/grlib/uart/apbuart_termios.c @@ -32,6 +32,7 @@ #include #include +#include #include static void apbuart_isr(void *arg) @@ -42,9 +43,9 @@ static void apbuart_isr(void *arg) char data; /* Get all received characters */ - while ((status=uart->regs->status) & APBUART_STATUS_DR) { + while ((status=grlib_load_32(&uart->regs->status)) & APBUART_STATUS_DR) { /* Data has arrived, get new data */ - data = uart->regs->data; + data = (char)grlib_load_32(&uart->regs->data); /* Tell termios layer about new character */ rtems_termios_enqueue_raw_characters(tty, &data, 1); @@ -52,7 +53,7 @@ static void apbuart_isr(void *arg) if ( (status & APBUART_STATUS_TE) - && (uart->regs->ctrl & APBUART_CTRL_TI) != 0 + && (grlib_load_32(&uart->regs->ctrl) & APBUART_CTRL_TI) != 0 ) { /* write_interrupt will get called from this function */ rtems_termios_dequeue_characters(tty, 1); @@ -67,23 +68,27 @@ static void apbuart_write_support( { struct apbuart_context *uart = (struct apbuart_context *) base; int sending; + uint32_t ctrl; + + ctrl = grlib_load_32(&uart->regs->ctrl); if (len > 0) { /* Enable TX interrupt (interrupt is edge-triggered) */ - uart->regs->ctrl |= APBUART_CTRL_TI; + ctrl |= APBUART_CTRL_TI; /* start UART TX, this will result in an interrupt when done */ - uart->regs->data = *buf; + grlib_store_32(&uart->regs->data, (uint8_t)*buf); sending = 1; } else { /* No more to send, disable TX interrupts */ - uart->regs->ctrl &= ~APBUART_CTRL_TI; + ctrl &= ~APBUART_CTRL_TI; /* Tell close that we sent everything */ sending = 0; } + grlib_store_32(&uart->regs->ctrl, ctrl); uart->sending = sending; } @@ -134,7 +139,7 @@ static bool apbuart_set_attributes( rtems_termios_device_lock_acquire(base, &lock_context); /* Read out current value */ - ctrl = uart->regs->ctrl; + ctrl = grlib_load_32(&uart->regs->ctrl); switch (t->c_cflag & (PARENB|PARODD)) { case (PARENB|PARODD): @@ -162,7 +167,7 @@ static bool apbuart_set_attributes( } /* Update new settings */ - uart->regs->ctrl = ctrl; + grlib_store_32(&uart->regs->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); @@ -173,7 +178,7 @@ static bool apbuart_set_attributes( scaler = (((uart->freq_hz * 10) / (baud * 8)) - 5) / 10; /* Set new baud rate by setting scaler */ - uart->regs->scaler = scaler; + grlib_store_32(&uart->regs->scaler, scaler); } return true; @@ -184,7 +189,8 @@ static void apbuart_set_best_baud( struct termios *term ) { - uint32_t baud = (uart->freq_hz * 10) / ((uart->regs->scaler * 10 + 5) * 8); + uint32_t baud = (uart->freq_hz * 10) / + ((grlib_load_32(&uart->regs->scaler) * 10 + 5) * 8); rtems_termios_set_best_baud(term, baud); } @@ -197,12 +203,15 @@ static bool apbuart_first_open_polled( ) { struct apbuart_context *uart = (struct apbuart_context *) base; + uint32_t ctrl; apbuart_set_best_baud(uart, term); /* Initialize UART on opening */ - uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; - uart->regs->status = 0; + ctrl = grlib_load_32(&uart->regs->ctrl); + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; + grlib_store_32(&uart->regs->ctrl, ctrl); + grlib_store_32(&uart->regs->status, 0); return true; } @@ -216,6 +225,7 @@ static bool apbuart_first_open_interrupt( { struct apbuart_context *uart = (struct apbuart_context *) base; rtems_status_code sc; + uint32_t ctrl; apbuart_set_best_baud(uart, term); @@ -229,11 +239,13 @@ static bool apbuart_first_open_interrupt( uart->sending = 0; /* Enable Receiver and transmitter and Turn on RX interrupts */ - uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE | - APBUART_CTRL_RI; + ctrl = grlib_load_32(&uart->regs->ctrl); + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE | APBUART_CTRL_RI; + grlib_store_32(&uart->regs->ctrl, ctrl); /* Initialize UART on opening */ - uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; - uart->regs->status = 0; + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; + grlib_store_32(&uart->regs->ctrl, ctrl); + grlib_store_32(&uart->regs->status, 0); return true; } @@ -246,10 +258,13 @@ static void apbuart_last_close_interrupt( { struct apbuart_context *uart = (struct apbuart_context *) base; rtems_interrupt_lock_context lock_context; + uint32_t ctrl; /* Turn off RX interrupts */ rtems_termios_device_lock_acquire(base, &lock_context); - uart->regs->ctrl &= ~(APBUART_CTRL_RI); + ctrl = grlib_load_32(&uart->regs->ctrl); + ctrl &= ~APBUART_CTRL_RI; + grlib_store_32(&uart->regs->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); /**** Flush device ****/ diff --git a/bsps/sparc/leon3/console/console.c b/bsps/sparc/leon3/console/console.c index 24484eb96f..891116b2c4 100644 --- a/bsps/sparc/leon3/console/console.c +++ b/bsps/sparc/leon3/console/console.c @@ -81,7 +81,7 @@ static int find_matching_apbuart(struct ambapp_dev *dev, int index, void *arg) struct ambapp_apb_info *apb = (struct ambapp_apb_info *)dev->devinfo; /* Extract needed information of one APBUART */ - apbuarts[uarts].regs = (struct apbuart_regs *)apb->start; + apbuarts[uarts].regs = (apbuart *)apb->start; apbuarts[uarts].irq = apb->common.irq; /* Get APBUART core frequency, it is assumed that it is the same * as Bus frequency where the UART is situated diff --git a/bsps/sparc/leon3/console/printk_support.c b/bsps/sparc/leon3/console/printk_support.c index 9fd1b1a089..cb77c66a96 100644 --- a/bsps/sparc/leon3/console/printk_support.c +++ b/bsps/sparc/leon3/console/printk_support.c @@ -35,14 +35,17 @@ */ #include -#include +#include #include #include #include #include +#include + +#include int leon3_debug_uart_index __attribute__((weak)) = 0; -struct apbuart_regs *leon3_debug_uart = NULL; +apbuart *leon3_debug_uart = NULL; static void bsp_debug_uart_init(void); @@ -105,15 +108,18 @@ static void bsp_debug_uart_init(void) ambapp_find_by_idx, (void *)&i); if (adev != NULL) { struct ambapp_apb_info *apb; + uint32_t ctrl; /* * Found a matching debug console, initialize debug UART if present for * printk(). */ apb = (struct ambapp_apb_info *)adev->devinfo; - leon3_debug_uart = (struct apbuart_regs *)apb->start; - leon3_debug_uart->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; - leon3_debug_uart->status = 0; + leon3_debug_uart = (apbuart *)apb->start; + ctrl = grlib_load_32(&leon3_debug_uart->ctrl); + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; + grlib_store_32(&leon3_debug_uart->ctrl, ctrl); + grlib_store_32(&leon3_debug_uart->status, 0); BSP_poll_char = bsp_debug_uart_poll_char; BSP_output_char = bsp_debug_uart_output_char; diff --git a/bsps/sparc/leon3/include/bsp/leon3.h b/bsps/sparc/leon3/include/bsp/leon3.h new file mode 100644 index 0000000000..a5559bc7b9 --- /dev/null +++ b/bsps/sparc/leon3/include/bsp/leon3.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSBSPsSPARCLEON3 + * + * @brief This header file provides interfaces used by the BSP implementation. + */ + +/* + * Copyright (C) 2021 embedded brains GmbH & Co. KG + * + * 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +#ifndef LIBBSP_SPARC_LEON3_BSP_LEON3_H +#define LIBBSP_SPARC_LEON3_BSP_LEON3_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup RTEMSBSPsSPARCLEON3 + * + * @{ + */ + +/** + * @brief This pointer provides the debug APBUART register block address. + */ +extern apbuart *leon3_debug_uart; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* LIBBSP_SPARC_LEON3_BSP_LEON3_H */ -- cgit v1.2.3