SerialDevice.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <Kernel/Devices/CharacterDevice.h>
  8. #include <Kernel/IO.h>
  9. namespace Kernel {
  10. class SerialDevice final : public CharacterDevice {
  11. AK_MAKE_ETERNAL
  12. public:
  13. static NonnullRefPtr<SerialDevice> must_create(size_t com_number);
  14. virtual ~SerialDevice() override;
  15. // ^CharacterDevice
  16. virtual bool can_read(const FileDescription&, size_t) const override;
  17. virtual KResultOr<size_t> read(FileDescription&, u64, UserOrKernelBuffer&, size_t) override;
  18. virtual bool can_write(const FileDescription&, size_t) const override;
  19. virtual KResultOr<size_t> write(FileDescription&, u64, const UserOrKernelBuffer&, size_t) override;
  20. void put_char(char);
  21. enum InterruptEnable {
  22. LowPowerMode = 0x01 << 5,
  23. SleepMode = 0x01 << 4,
  24. ModemStatusInterrupt = 0x01 << 3,
  25. ReceiverLineStatusInterrupt = 0x01 << 2,
  26. TransmitterHoldingRegisterEmptyInterrupt = 0x01 << 1,
  27. ReceivedDataAvailableInterrupt = 0x01 << 0
  28. };
  29. enum Baud {
  30. Baud50 = 2304,
  31. Baud110 = 1047,
  32. Baud220 = 524,
  33. Baud300 = 384,
  34. Baud600 = 192,
  35. Baud1200 = 96,
  36. Baud2400 = 48,
  37. Baud4800 = 24,
  38. Baud9600 = 12,
  39. Baud19200 = 6,
  40. Baud38400 = 3,
  41. Baud57600 = 2,
  42. Baud115200 = 1
  43. };
  44. enum ParitySelect {
  45. None = 0x00 << 3,
  46. Odd = 0x01 << 3,
  47. Even = 0x03 << 3,
  48. Mark = 0x05 << 3,
  49. Space = 0x07 << 3
  50. };
  51. enum StopBits {
  52. One = 0x00 << 2,
  53. Two = 0x01 << 2
  54. };
  55. enum WordLength {
  56. FiveBits = 0x00,
  57. SixBits = 0x01,
  58. SevenBits = 0x02,
  59. EightBits = 0x03
  60. };
  61. enum FIFOControl {
  62. EnableFIFO = 0x01 << 0,
  63. ClearReceiveFIFO = 0x01 << 1,
  64. ClearTransmitFIFO = 0x01 << 2,
  65. Enable64ByteFIFO = 0x01 << 5,
  66. TriggerLevel1 = 0x00 << 6,
  67. TriggerLevel2 = 0x01 << 6,
  68. TriggerLevel3 = 0x02 << 6,
  69. TriggerLevel4 = 0x03 << 6
  70. };
  71. enum ModemControl {
  72. AutoflowControlEnabled = 0x01 << 5,
  73. LoopbackMode = 0x01 << 4,
  74. AuxiliaryOutput2 = 0x01 << 3,
  75. AuxiliaryOutput1 = 0x01 << 2,
  76. RequestToSend = 0x01 << 1,
  77. DataTerminalReady = 0x01 << 0
  78. };
  79. enum LineStatus {
  80. ErrorInReceivedFIFO = 0x01 << 7,
  81. EmptyDataHoldingRegisters = 0x01 << 6,
  82. EmptyTransmitterHoldingRegister = 0x01 << 5,
  83. BreakInterrupt = 0x01 << 4,
  84. FramingError = 0x01 << 3,
  85. ParityError = 0x01 << 2,
  86. OverrunError = 0x01 << 1,
  87. DataReady = 0x01 << 0
  88. };
  89. // ^Device
  90. virtual mode_t required_mode() const override { return 0620; }
  91. virtual String device_name() const override;
  92. private:
  93. friend class PCISerialDevice;
  94. SerialDevice(IOAddress base_addr, unsigned minor);
  95. // ^CharacterDevice
  96. virtual StringView class_name() const override { return "SerialDevice"; }
  97. void initialize();
  98. void set_interrupts(bool interrupt_enable);
  99. void set_baud(Baud);
  100. void set_fifo_control(u8 fifo_control);
  101. void set_line_control(ParitySelect, StopBits, WordLength);
  102. void set_break_enable(bool break_enable);
  103. void set_modem_control(u8 modem_control);
  104. u8 get_line_status() const;
  105. IOAddress m_base_addr;
  106. bool m_interrupt_enable { false };
  107. u8 m_fifo_control { 0 };
  108. Baud m_baud { Baud38400 };
  109. ParitySelect m_parity_select { None };
  110. StopBits m_stop_bits { One };
  111. WordLength m_word_length { EightBits };
  112. bool m_break_enable { false };
  113. u8 m_modem_control { 0 };
  114. bool m_last_put_char_was_carriage_return { false };
  115. Spinlock<u8> m_serial_lock;
  116. };
  117. }