pdc_cons.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * PDC early console support - use PDC firmware to dump text via boot console
  4. *
  5. * Copyright (C) 2001-2022 Helge Deller <[email protected]>
  6. */
  7. #include <linux/console.h>
  8. #include <linux/init.h>
  9. #include <linux/serial_core.h>
  10. #include <linux/kgdb.h>
  11. #include <asm/page.h> /* for PAGE0 */
  12. #include <asm/pdc.h> /* for iodc_call() proto and friends */
  13. static void pdc_console_write(struct console *co, const char *s, unsigned count)
  14. {
  15. int i = 0;
  16. do {
  17. i += pdc_iodc_print(s + i, count - i);
  18. } while (i < count);
  19. }
  20. #ifdef CONFIG_KGDB
  21. static int kgdb_pdc_read_char(void)
  22. {
  23. int c = pdc_iodc_getc();
  24. return (c <= 0) ? NO_POLL_CHAR : c;
  25. }
  26. static void kgdb_pdc_write_char(u8 chr)
  27. {
  28. /* no need to print char as it's shown on standard console */
  29. /* pdc_iodc_print(&chr, 1); */
  30. }
  31. static struct kgdb_io kgdb_pdc_io_ops = {
  32. .name = "kgdb_pdc",
  33. .read_char = kgdb_pdc_read_char,
  34. .write_char = kgdb_pdc_write_char,
  35. };
  36. #endif
  37. static int __init pdc_earlycon_setup(struct earlycon_device *device,
  38. const char *opt)
  39. {
  40. struct console *earlycon_console;
  41. /* If the console is duplex then copy the COUT parameters to CIN. */
  42. if (PAGE0->mem_cons.cl_class == CL_DUPLEX)
  43. memcpy(&PAGE0->mem_kbd, &PAGE0->mem_cons, sizeof(PAGE0->mem_cons));
  44. earlycon_console = device->con;
  45. earlycon_console->write = pdc_console_write;
  46. device->port.iotype = UPIO_MEM32BE;
  47. #ifdef CONFIG_KGDB
  48. kgdb_register_io_module(&kgdb_pdc_io_ops);
  49. #endif
  50. return 0;
  51. }
  52. EARLYCON_DECLARE(pdc, pdc_earlycon_setup);