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