tty.c 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. /* Copyright 2018 SiFive, Inc */
  2. /* SPDX-License-Identifier: Apache-2.0 */
  3. #include <metal/uart.h>
  4. #include <metal/tty.h>
  5. #include <metal/machine.h>
  6. #if defined(__METAL_DT_STDOUT_UART_HANDLE)
  7. /* This implementation serves as a small shim that interfaces with the first
  8. * UART on a system. */
  9. int metal_tty_putc(int c)
  10. {
  11. if (c == '\n') {
  12. metal_tty_putc_raw( '\r' );
  13. }
  14. return metal_tty_putc_raw( c );
  15. }
  16. int metal_tty_putc_raw(int c)
  17. {
  18. return metal_uart_putc(__METAL_DT_STDOUT_UART_HANDLE, c);
  19. }
  20. int metal_tty_getc(int *c)
  21. {
  22. do {
  23. metal_uart_getc( __METAL_DT_STDOUT_UART_HANDLE, c );
  24. /* -1 means no key pressed, getc waits */
  25. } while( -1 == *c )
  26. ;
  27. return 0;
  28. }
  29. #ifndef __METAL_DT_STDOUT_UART_BAUD
  30. #define __METAL_DT_STDOUT_UART_BAUD 115200
  31. #endif
  32. static void metal_tty_init(void) __attribute__((constructor));
  33. static void metal_tty_init(void)
  34. {
  35. metal_uart_init(__METAL_DT_STDOUT_UART_HANDLE, __METAL_DT_STDOUT_UART_BAUD);
  36. }
  37. #else
  38. /* This implementation of putc doesn't actually do anything, it's just there to
  39. * provide a shim that eats all the characters so we can ensure that everything
  40. * can link to metal_tty_putc. */
  41. int nop_putc(int c) __attribute__((section(".text.metal.nop.putc")));
  42. int nop_putc(int c) { return -1; }
  43. int metal_tty_putc(int c) __attribute__((weak, alias("nop_putc")));
  44. #pragma message("There is no default output device, metal_tty_putc() will throw away all input.")
  45. #endif