ns8250-spcr.c 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 2022 Free Software Foundation, Inc.
  4. *
  5. * GRUB is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * GRUB is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #if !defined(GRUB_MACHINE_IEEE1275) && !defined(GRUB_MACHINE_QEMU)
  19. #include <grub/misc.h>
  20. #include <grub/serial.h>
  21. #include <grub/ns8250.h>
  22. #include <grub/types.h>
  23. #include <grub/dl.h>
  24. #include <grub/acpi.h>
  25. struct grub_serial_port *
  26. grub_ns8250_spcr_init (void)
  27. {
  28. struct grub_acpi_spcr *spcr;
  29. struct grub_serial_config config;
  30. spcr = grub_acpi_find_table (GRUB_ACPI_SPCR_SIGNATURE);
  31. if (spcr == NULL)
  32. return NULL;
  33. if (spcr->hdr.revision < 2)
  34. grub_dprintf ("serial", "SPCR table revision %d < 2, continuing anyway\n",
  35. (int) spcr->hdr.revision);
  36. if (spcr->intf_type != GRUB_ACPI_SPCR_INTF_TYPE_16550 &&
  37. spcr->intf_type != GRUB_ACPI_SPCR_INTF_TYPE_16550_DBGP &&
  38. spcr->intf_type != GRUB_ACPI_SPCR_INTF_TYPE_16550_DBG2)
  39. return NULL;
  40. /* For now, we only support byte accesses. */
  41. if (spcr->base_addr.access_size != GRUB_ACPI_GENADDR_SIZE_BYTE &&
  42. spcr->base_addr.access_size != GRUB_ACPI_GENADDR_SIZE_LGCY)
  43. return NULL;
  44. config.word_len = 8;
  45. config.parity = GRUB_SERIAL_PARITY_NONE;
  46. config.stop_bits = GRUB_SERIAL_STOP_BITS_1;
  47. config.base_clock = UART_DEFAULT_BASE_CLOCK;
  48. if (spcr->flow_control & GRUB_ACPI_SPCR_FC_RTSCTS)
  49. config.rtscts = 1;
  50. else
  51. config.rtscts = 0;
  52. switch (spcr->baud_rate)
  53. {
  54. case GRUB_ACPI_SPCR_BAUD_9600:
  55. config.speed = 9600;
  56. break;
  57. case GRUB_ACPI_SPCR_BAUD_19200:
  58. config.speed = 19200;
  59. break;
  60. case GRUB_ACPI_SPCR_BAUD_57600:
  61. config.speed = 57600;
  62. break;
  63. case GRUB_ACPI_SPCR_BAUD_115200:
  64. config.speed = 115200;
  65. break;
  66. case GRUB_ACPI_SPCR_BAUD_CURRENT:
  67. default:
  68. /*
  69. * We don't (yet) have a way to read the currently
  70. * configured speed in HW, so let's use a sane default.
  71. */
  72. config.speed = 115200;
  73. break;
  74. };
  75. switch (spcr->base_addr.space_id)
  76. {
  77. case GRUB_ACPI_GENADDR_MEM_SPACE:
  78. return grub_serial_ns8250_add_mmio (spcr->base_addr.addr,
  79. spcr->base_addr.access_size, &config);
  80. case GRUB_ACPI_GENADDR_IO_SPACE:
  81. return grub_serial_ns8250_add_port (spcr->base_addr.addr, &config);
  82. default:
  83. return NULL;
  84. };
  85. }
  86. #endif