serial_port_intel_x64.cpp
Go to the documentation of this file.
1 //
2 // Bareflank Hypervisor
3 //
4 // Copyright (C) 2015 Assured Information Security, Inc.
5 // Author: Rian Quinn <quinnr@ainfosec.com>
6 // Author: Brendan Kerrigan <kerriganb@ainfosec.com>
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 
23 
24 using namespace x64;
25 using namespace serial_intel_x64;
26 
28  m_port(port)
29 {
31 
32  this->disable_dlab();
33 
37 
38  portio::outb(m_port + interrupt_en_reg, 0x00);
39  portio::outb(m_port + fifo_control_reg, bits);
40 
41  this->set_baud_rate(DEFAULT_BAUD_RATE);
42  this->set_data_bits(DEFAULT_DATA_BITS);
43  this->set_stop_bits(DEFAULT_STOP_BITS);
44  this->set_parity_bits(DEFAULT_PARITY_BITS);
45 }
46 
49 {
50  static serial_port_intel_x64 serial{};
51  return &serial;
52 }
53 
54 void
56 {
57  auto lsb = (rate & 0x000000FF) >> 0;
58  auto msb = (rate & 0x0000FF00) >> 8;
59 
60  this->enable_dlab();
61 
62  portio::outb(m_port + baud_rate_lo_reg, lsb);
63  portio::outb(m_port + baud_rate_hi_reg, msb);
64 
65  this->disable_dlab();
66 }
67 
70 {
71  this->enable_dlab();
72 
73  auto lsb = portio::inb(m_port + baud_rate_lo_reg);
74  auto msb = portio::inb(m_port + baud_rate_hi_reg);
75 
76  this->disable_dlab();
77 
78  switch ((msb << 8) | lsb)
79  {
80  case baud_rate_50:
81  return baud_rate_50;
82  case baud_rate_75:
83  return baud_rate_75;
84  case baud_rate_110:
85  return baud_rate_110;
86  case baud_rate_150:
87  return baud_rate_150;
88  case baud_rate_300:
89  return baud_rate_300;
90  case baud_rate_600:
91  return baud_rate_600;
92  case baud_rate_1200:
93  return baud_rate_1200;
94  case baud_rate_1800:
95  return baud_rate_1800;
96  case baud_rate_2000:
97  return baud_rate_2000;
98  case baud_rate_2400:
99  return baud_rate_2400;
100  case baud_rate_3600:
101  return baud_rate_3600;
102  case baud_rate_4800:
103  return baud_rate_4800;
104  case baud_rate_7200:
105  return baud_rate_7200;
106  case baud_rate_9600:
107  return baud_rate_9600;
108  case baud_rate_19200:
109  return baud_rate_19200;
110  case baud_rate_38400:
111  return baud_rate_38400;
112  case baud_rate_57600:
113  return baud_rate_57600;
114  default:
115  return baud_rate_115200;
116  }
117 }
118 
119 void
121 {
122  auto reg = portio::inb(m_port + line_control_reg);
123 
124  reg = reg & gsl::narrow_cast<decltype(reg)>(~line_control_data_mask);
125  reg = reg | gsl::narrow_cast<decltype(reg)>(bits & line_control_data_mask);
126 
127  portio::outb(m_port + line_control_reg, reg);
128 }
129 
132 {
133  auto reg = portio::inb(m_port + line_control_reg);
134 
135  switch (reg & line_control_data_mask)
136  {
137  case char_length_5:
138  return char_length_5;
139  case char_length_6:
140  return char_length_6;
141  case char_length_7:
142  return char_length_7;
143  default:
144  return char_length_8;
145  }
146 }
147 
148 void
150 {
151  auto reg = portio::inb(m_port + line_control_reg);
152 
153  reg = reg & gsl::narrow_cast<decltype(reg)>(~line_control_stop_mask);
154  reg = reg | gsl::narrow_cast<decltype(reg)>(bits & line_control_stop_mask);
155 
156  portio::outb(m_port + line_control_reg, reg);
157 }
158 
161 {
162  auto reg = portio::inb(m_port + line_control_reg);
163 
164  switch (reg & line_control_stop_mask)
165  {
166  case stop_bits_1:
167  return stop_bits_1;
168  default:
169  return stop_bits_2;
170  }
171 }
172 
173 void
175 {
176  auto reg = portio::inb(m_port + line_control_reg);
177 
178  reg = reg & gsl::narrow_cast<decltype(reg)>(~line_control_parity_mask);
179  reg = reg | gsl::narrow_cast<decltype(reg)>(bits & line_control_parity_mask);
180 
181  portio::outb(m_port + line_control_reg, reg);
182 }
183 
186 {
187  auto reg = portio::inb(m_port + line_control_reg);
188 
189  switch (reg & line_control_parity_mask)
190  {
191  case parity_odd:
192  return parity_odd;
193  case parity_even:
194  return parity_even;
195  case parity_mark:
196  return parity_mark;
197  case parity_space:
198  return parity_space;
199  default:
200  return parity_none;
201  }
202 }
203 
204 void
206 {
207  while (!get_line_status_empty_transmitter());
208  portio::outb(m_port, c);
209 }
210 
211 void
212 serial_port_intel_x64::enable_dlab() const noexcept
213 {
214  auto reg = portio::inb(m_port + line_control_reg);
215  reg = reg | gsl::narrow_cast<decltype(reg)>(dlab);
216  portio::outb(m_port + line_control_reg, reg);
217 }
218 
219 void
220 serial_port_intel_x64::disable_dlab() const noexcept
221 {
222  auto reg = portio::inb(m_port + line_control_reg);
223  reg = reg & gsl::narrow_cast<decltype(reg)>(~(dlab));
224  portio::outb(m_port + line_control_reg, reg);
225 }
226 
227 bool
228 serial_port_intel_x64::get_line_status_empty_transmitter() const noexcept
229 {
231 }
auto inb(P port) noexcept
Definition: portio_x64.h:65
constexpr const x64::portio::port_8bit_type dlab
parity_bits_t parity_bits() const noexcept
void set_parity_bits(parity_bits_t bits) noexcept
baud_rate_t baud_rate() const noexcept
constexpr const x64::portio::port_8bit_type line_control_parity_mask
x64::portio::port_8bit_type value_type
constexpr const x64::portio::port_8bit_type line_control_stop_mask
serial_port_intel_x64(port_type port=DEFAULT_COM_PORT) noexcept
data_bits_t data_bits() const noexcept
void write(char c) noexcept
#define DEFAULT_BAUD_RATE
Definition: constants.h:298
void outb(P port, T val) noexcept
Definition: portio_x64.h:112
constexpr const x64::portio::port_8bit_type line_status_empty_transmitter
constexpr const x64::portio::port_8bit_type fifo_control_clear_transmit_fifo
constexpr const x64::portio::port_addr_type line_status_reg
constexpr const x64::portio::port_8bit_type line_control_data_mask
void uint64_t uint64_t uint64_t *rdx noexcept
void set_stop_bits(stop_bits_t bits) noexcept
constexpr const x64::portio::port_addr_type baud_rate_lo_reg
x64::portio::port_addr_type port_type
void set_baud_rate(baud_rate_t rate) noexcept
static serial_port_intel_x64 * instance() noexcept
constexpr const x64::portio::port_addr_type line_control_reg
#define DEFAULT_STOP_BITS
Definition: constants.h:316
constexpr const x64::portio::port_addr_type baud_rate_hi_reg
#define DEFAULT_PARITY_BITS
Definition: constants.h:325
void set_data_bits(data_bits_t bits) noexcept
#define DEFAULT_DATA_BITS
Definition: constants.h:307
Definition: cache_x64.h:31
stop_bits_t stop_bits() const noexcept
constexpr const x64::portio::port_8bit_type fifo_control_enable_fifos
constexpr const x64::portio::port_addr_type fifo_control_reg
constexpr const x64::portio::port_8bit_type fifo_control_clear_recieve_fifo
constexpr const x64::portio::port_addr_type interrupt_en_reg