blob: 3061924517617534112f960b23b08f19023a151f [file] [log] [blame]
/* Copyright 2018 SiFive, Inc */
/* SPDX-License-Identifier: Apache-2.0 */
#include <metal/uart.h>
#include <metal/tty.h>
#include <metal/machine.h>
#if defined(__METAL_DT_STDOUT_UART_HANDLE)
/* This implementation serves as a small shim that interfaces with the first
* UART on a system. */
int metal_tty_putc(int c)
{
if (c == '\n') {
metal_tty_putc_raw( '\r' );
}
return metal_tty_putc_raw( c );
}
int metal_tty_putc_raw(int c)
{
return metal_uart_putc(__METAL_DT_STDOUT_UART_HANDLE, c);
}
int metal_tty_getc(int *c)
{
do {
metal_uart_getc( __METAL_DT_STDOUT_UART_HANDLE, c );
/* -1 means no key pressed, getc waits */
} while( -1 == *c )
;
return 0;
}
#ifndef __METAL_DT_STDOUT_UART_BAUD
#define __METAL_DT_STDOUT_UART_BAUD 115200
#endif
static void metal_tty_init(void) __attribute__((constructor));
static void metal_tty_init(void)
{
metal_uart_init(__METAL_DT_STDOUT_UART_HANDLE, __METAL_DT_STDOUT_UART_BAUD);
}
#else
/* This implementation of putc doesn't actually do anything, it's just there to
* provide a shim that eats all the characters so we can ensure that everything
* can link to metal_tty_putc. */
int nop_putc(int c) __attribute__((section(".text.metal.nop.putc")));
int nop_putc(int c) { return -1; }
int metal_tty_putc(int c) __attribute__((weak, alias("nop_putc")));
#pragma message("There is no default output device, metal_tty_putc() will throw away all input.")
#endif