SayoriOS  0.3.3
serial_port.c
1 
10 #include <lib/string.h>
11 #include <io/serial_port.h>
12 #include <stdarg.h>
13 #include "io/ports.h"
14 #include "drv/fpu.h"
15 #include "lib/math.h"
16 
17 uint16_t com_init[8] = {0};
18 
25 void __com_setInit(uint16_t key, uint16_t value){
26  com_init[key] = value;
27 }
28 
36 uint16_t __com_getInit(uint16_t key){
37  return com_init[key];
38 }
39 
40 void __com_readBigData(uint16_t port, uint32_t *buffer, size_t times) {
41  for (int32_t index = 0; index < times; index++) {
42  buffer[index] = inl(port);
43  }
44 }
45 
46 
54 void __com_writeBigData(uint16_t port, uint32_t *buffer, size_t times) {
55  for (int32_t index = 0; index < times; index++) {
56  outl(port, buffer[index]);
57  }
58 }
59 
67 void __com_readString(uint16_t port, uint32_t *buf, size_t size){
68  __com_readBigData(port, buf, size);
69 }
70 
76 int32_t __com_is_ready(uint16_t port){
77  return inb(port + 5) & 0x20;
78 }
79 
85 void __com_writeChar(uint16_t port,char a) {
86  while (__com_is_ready(port) == 0);
87  outb(port, a);
88 }
89 
90 /*
91 * @brief Запись строки через порт
92  *
93  * @param port - Порт
94  * @param buff - Строка
95 */
96 void __com_writeString(uint16_t port, char *buf){
97  for (size_t i = 0, len = strlen(buf); i < len; i++) {
98  __com_writeChar(port, buf[i]);
99  }
100 }
101 
107 void __com_io_wait(){
108  outb(0x80, 0);
109 }
110 
111 
112 void __com_writeInt(int16_t port, ssize_t i){
113  char buffer[44] = {0};
114  int index = 0;
115 
116  if(i == 0) {
117  __com_writeChar(port, '0');
118  return;
119  }
120 
121  if(i < 0) {
122  i = -i;
123  __com_writeChar(port, '-');
124  }
125 
126  while(i > 0) {
127  buffer[index++] = '0' + (i % 10);
128  i /= 10;
129  }
130 
131  while(index--) {
132  __com_writeChar(port, buffer[index]);
133  }
134 }
135 
136 void __com_writeUInt(int16_t port, size_t i){
137  char buffer[44] = {0};
138  int index = 0;
139 
140  while(i != 0) {
141  buffer[index++] = '0' + (i % 10);
142  i /= 10;
143  }
144 
145  while(index--) {
146  __com_writeChar(port, buffer[index]);
147  }
148 }
149 
150 
151 void __com_writeHex(int16_t port, uint32_t i, bool mode){
152  const unsigned char hex[16] = "0123456789ABCDEF";
153  uint32_t n = i;
154  uint32_t d = 0x10000000;
155 
156  if(mode)
157  __com_writeString(port, "0x");
158 
159  while ((i / d == 0) && (d >= 0x10)) {
160  d /= 0x10;
161  }
162 
163  while (d >= 0xF) {
164  __com_writeChar(port,(char)hex[n / d]);
165  n = n % d;
166  d /= 0x10;
167  }
168  __com_writeChar(port,(char)hex[n]);
169 }
170 
171 void __com_pre_formatString(int16_t port, const char* format, va_list args){
172  int32_t i = 0;
173  char *string;
174 
175  while (format[i]) {
176  if (format[i] == '%') {
177  i++;
178  switch (format[i]) {
179  case 's':
180  string = va_arg(args, char*);
181  __com_writeString(port, string ? string : "(nullptr)");
182  break;
183  case 'c':
184  __com_writeChar(port, va_arg(args, int));
185  break;
186  case 'd':
187  __com_writeInt(port,va_arg(args, int));
188  break;
189  case 'f': {
190  double a = va_arg(args, double);
191 
192  if(!fpu_isInitialized()) {
193  __com_writeString(port,"!0.0000000");
194  break;
195  }
196 
197  if((int)a < 0) {
198  a = -a;
199  __com_writeChar(port,'-');
200  }
201 
202  double rem = a - (int)a;
203  __com_writeInt(port,(int)a);
204  __com_writeChar(port,'.');
205 
206  for(int n = 0; n < 7; n++) {
207  __com_writeInt(
208  port,
209  (unsigned int)(rem * ipow(10, n + 1)) % 10
210  );
211  }
212 
213  break;
214  }
215  case 'i':
216  __com_writeInt(port,va_arg(args, int));
217  break;
218  case 'u':
219  __com_writeUInt(port,va_arg(args, unsigned int));
220  break;
221  case 'x':
222  __com_writeHex(port,va_arg(args, uint32_t),true);
223  break;
224  case 'v':
225  __com_writeHex(port,va_arg(args, uint32_t),false);
226  break;
227  default:
228  __com_writeChar(port,format[i]);
229  break;
230  }
231  } else {
232  __com_writeChar(port,format[i]);
233  }
234  i++;
235  }
236 }
237 
243 void __com_formatString(int16_t port, char *text, ...) {
244  va_list args;
245  va_start(args, text);
246  if (__com_getInit(1) == 1){
247  __com_pre_formatString(port,text, args);
248  }
249  va_end(args);
250 }
251 
252 
256 int __com_init(uint16_t port) {
257  outb(port + 1, 0x00); // Disable all interrupts
258  outb(port + 3, 0x80); // Enable DLAB (set baud rate divisor)
259  outb(port + 0, 0x03); // Set divisor to 1 (lo byte) 115200 / divisor (1) = 115200 baud
260  outb(port + 1, 0x00); // (hi byte)
261  outb(port + 3, 0x03); // 8 bits, no parity, one stop bit
262  outb(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
263  outb(port + 4, 0x0B); // IRQs enabled, RTS/DSR set
264  outb(port + 4, 0x1E); // Set in loopback mode, test the serial chip
265  outb(port + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
266 
267  if(inb(port + 0) != 0xAE) {
268  return 1;
269  }
270 
271  // If serial is not faulty set it in normal operation mode
272  // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
273  outb(port + 4, 0x0F);
274 
275  return 0;
276 }
uint32_t mode
Режим работы (0 - Обычный | 1 - Режим логирования)
Definition: bootscreen.c:23
bool fpu_isInitialized()
Возвращает статус FPU.
Definition: fpu.c:15
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
Definition: string.h:10
Definition: stdarg.h:9