Releasing debian version 3:6.03+dfsg-10.
[syslinux-debian.git] / com32 / lib / vdprintf.c
blobbcf55bb7dda9a8dae64a9e26d3bca77ad9f6727a
1 /*
2 * vdprintf.c
3 */
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdarg.h>
8 #include <unistd.h>
9 #include <inttypes.h>
10 #include <sys/io.h>
11 #include <sys/cpu.h>
13 #ifdef DEBUG_PORT
15 #define BUFFER_SIZE 4096
17 enum serial_port_regs {
18 THR = 0,
19 RBR = 0,
20 DLL = 0,
21 DLM = 1,
22 IER = 1,
23 IIR = 2,
24 FCR = 2,
25 LCR = 3,
26 MCR = 4,
27 LSR = 5,
28 MSR = 6,
29 SCR = 7,
32 static const uint16_t debug_base = DEBUG_PORT;
34 static void debug_putc(char c)
36 if (c == '\n')
37 debug_putc('\r');
39 while ((inb(debug_base + LSR) & 0x20) == 0)
40 cpu_relax();
41 outb(c, debug_base + THR);
44 void vdprintf(const char *format, va_list ap)
46 int rv;
47 char buffer[BUFFER_SIZE];
48 char *p;
49 static bool debug_init = false;
50 static bool debug_ok = false;
52 rv = vsnprintf(buffer, BUFFER_SIZE, format, ap);
53 if (rv < 0)
54 return;
56 if (rv > BUFFER_SIZE - 1)
57 rv = BUFFER_SIZE - 1;
60 * This unconditionally outputs to a serial port at 0x3f8 regardless of
61 * if one is enabled or not (this means we don't have to enable the real
62 * serial console and therefore get conflicting output.)
64 if (__unlikely(!debug_init)) {
65 uint8_t dll, dlm, lcr;
67 debug_init = true;
69 cli();
71 /* Initialize the serial port to 115200 n81 with FIFOs enabled */
72 outb(0x83, debug_base + LCR);
73 outb(0x01, debug_base + DLL);
74 outb(0x00, debug_base + DLM);
75 (void)inb(debug_base + IER); /* Synchronize */
76 dll = inb(debug_base + DLL);
77 dlm = inb(debug_base + DLM);
78 lcr = inb(debug_base + LCR);
80 outb(0x03, debug_base + LCR);
81 (void)inb(debug_base + IER); /* Synchronize */
83 outb(0x00, debug_base + IER);
84 (void)inb(debug_base + IER); /* Synchronize */
86 sti();
88 if (dll != 0x01 || dlm != 0x00 || lcr != 0x83) {
89 /* No serial port present */
90 return;
93 outb(0x01, debug_base + FCR);
94 (void)inb(debug_base + IER); /* Synchronize */
95 if (inb(debug_base + IIR) < 0xc0) {
96 outb(0x00, debug_base + FCR); /* Disable non-functional FIFOs */
97 (void)inb(debug_base + IER); /* Synchronize */
100 debug_ok = true;
103 if (!debug_ok)
104 return;
106 p = buffer;
107 while (rv--)
108 debug_putc(*p++);
111 #endif /* DEBUG_PORT */