summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Jones <ajones@ventanamicro.com>2022-07-18 20:20:28 +0300
committerAnup Patel <anup@brainfault.org>2022-07-30 09:09:42 +0300
commitf27203525aa2fc20d0074feb892a6f8433f84e3a (patch)
treedb3f886de35c8bd270564e97278ae9ab08833d95
parent7198e1d06f486173e6565ff6c718f30bf8c2ff30 (diff)
downloadopensbi-f27203525aa2fc20d0074feb892a6f8433f84e3a.tar.xz
lib: utils/serial: Ensure baudrate is non-zero before using
RISC-V doesn't generate exceptions on divide-by-zero, but the result, all bits set, is not likely what people expect either. In all cases where we divide by baudrate there's a chance it's zero (when the DT it came from is "bad"). To avoid difficult to debug situations, leave baudrate dependent registers alone when baudrate is zero, as, also in all cases, it appears we can skip initialization of those registers and still [hopefully] have a functioning UART. Signed-off-by: Andrew Jones <ajones@ventanamicro.com> Reviewed-by: Anup Patel <anup@brainfault.org>
-rw-r--r--lib/utils/serial/gaisler-uart.c2
-rw-r--r--lib/utils/serial/shakti-uart.c8
-rw-r--r--lib/utils/serial/sifive-uart.c2
-rw-r--r--lib/utils/serial/uart8250.c7
4 files changed, 13 insertions, 6 deletions
diff --git a/lib/utils/serial/gaisler-uart.c b/lib/utils/serial/gaisler-uart.c
index 5f30ee4..eec75cc 100644
--- a/lib/utils/serial/gaisler-uart.c
+++ b/lib/utils/serial/gaisler-uart.c
@@ -70,7 +70,7 @@ int gaisler_uart_init(unsigned long base, u32 in_freq, u32 baudrate)
uart_base = (volatile char *)base;
/* Configure baudrate */
- if (in_freq)
+ if (in_freq && baudrate)
set_reg(UART_REG_SCALER, in_freq / (baudrate * 8 + 7));
ctrl = get_reg(UART_REG_CTRL);
diff --git a/lib/utils/serial/shakti-uart.c b/lib/utils/serial/shakti-uart.c
index 3556935..8769cb2 100644
--- a/lib/utils/serial/shakti-uart.c
+++ b/lib/utils/serial/shakti-uart.c
@@ -47,8 +47,12 @@ static struct sbi_console_device shakti_console = {
int shakti_uart_init(unsigned long base, u32 in_freq, u32 baudrate)
{
uart_base = (volatile char *)base;
- u16 baud = (u16)(in_freq/(16 * baudrate));
- writew(baud, uart_base + REG_BAUD);
+ u16 baud;
+
+ if (baudrate) {
+ baud = (u16)(in_freq / (16 * baudrate));
+ writew(baud, uart_base + REG_BAUD);
+ }
sbi_console_set_device(&shakti_console);
diff --git a/lib/utils/serial/sifive-uart.c b/lib/utils/serial/sifive-uart.c
index 7078611..3581d47 100644
--- a/lib/utils/serial/sifive-uart.c
+++ b/lib/utils/serial/sifive-uart.c
@@ -97,7 +97,7 @@ int sifive_uart_init(unsigned long base, u32 in_freq, u32 baudrate)
uart_baudrate = baudrate;
/* Configure baudrate */
- if (in_freq)
+ if (in_freq && baudrate)
set_reg(UART_REG_DIV, uart_min_clk_divisor(in_freq, baudrate));
/* Disable interrupts */
diff --git a/lib/utils/serial/uart8250.c b/lib/utils/serial/uart8250.c
index 38ea11a..99bf1bf 100644
--- a/lib/utils/serial/uart8250.c
+++ b/lib/utils/serial/uart8250.c
@@ -93,7 +93,7 @@ static struct sbi_console_device uart8250_console = {
int uart8250_init(unsigned long base, u32 in_freq, u32 baudrate, u32 reg_shift,
u32 reg_width, u32 reg_offset)
{
- u16 bdiv;
+ u16 bdiv = 0;
uart8250_base = (volatile char *)base + reg_offset;
uart8250_reg_shift = reg_shift;
@@ -101,7 +101,10 @@ int uart8250_init(unsigned long base, u32 in_freq, u32 baudrate, u32 reg_shift,
uart8250_in_freq = in_freq;
uart8250_baudrate = baudrate;
- bdiv = (uart8250_in_freq + 8 * uart8250_baudrate) / (16 * uart8250_baudrate);
+ if (uart8250_baudrate) {
+ bdiv = (uart8250_in_freq + 8 * uart8250_baudrate) /
+ (16 * uart8250_baudrate);
+ }
/* Disable all interrupts */
set_reg(UART_IER_OFFSET, 0x00);