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 }
mode
uint32_t mode
Режим работы (0 - Обычный | 1 - Режим логирования)
Definition: bootscreen.c:23
fpu_isInitialized
bool fpu_isInitialized()
Возвращает статус FPU.
Definition: fpu.c:15
strlen
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
string
Definition: string.h:10
va_list
Definition: stdarg.h:9