blob: 319a85c16bfc9b6426c52f966879b224fb28c03d [file] [log] [blame]
Kevin O'Connor4cd522e2013-11-29 12:14:34 -05001// Low-level serial (and serial-like) device access.
2//
3// Copyright (C) 2008-1013 Kevin O'Connor <kevin@koconnor.net>
4//
5// This file may be distributed under the terms of the GNU LGPLv3 license.
6
7#include "config.h" // CONFIG_DEBUG_SERIAL
8#include "fw/paravirt.h" // RunningOnQEMU
9#include "output.h" // dprintf
10#include "serialio.h" // serial_debug_preinit
11#include "x86.h" // outb
12
13
14/****************************************************************
15 * Serial port debug output
16 ****************************************************************/
17
18#define DEBUG_TIMEOUT 100000
19
Ricardo Ribalda Delgado93329652016-12-20 19:03:58 +010020// Write to a serial port register
21static void
22serial_debug_write(u8 offset, u8 val)
23{
24 if (CONFIG_DEBUG_SERIAL) {
25 outb(val, CONFIG_DEBUG_SERIAL_PORT + offset);
26 } else if (CONFIG_DEBUG_SERIAL_MMIO) {
27 ASSERT32FLAT();
28 writeb((void*)CONFIG_DEBUG_SERIAL_MEM_ADDRESS + 4*offset, val);
29 }
30}
31
32// Read from a serial port register
33static u8
34serial_debug_read(u8 offset)
35{
36 if (CONFIG_DEBUG_SERIAL)
37 return inb(CONFIG_DEBUG_SERIAL_PORT + offset);
38 if (CONFIG_DEBUG_SERIAL_MMIO) {
39 ASSERT32FLAT();
40 return readb((void*)CONFIG_DEBUG_SERIAL_MEM_ADDRESS + 4*offset);
41 }
42}
43
Kevin O'Connor4cd522e2013-11-29 12:14:34 -050044// Setup the debug serial port for output.
45void
46serial_debug_preinit(void)
47{
Ricardo Ribalda Delgado93329652016-12-20 19:03:58 +010048 if (!CONFIG_DEBUG_SERIAL && (!CONFIG_DEBUG_SERIAL_MMIO || MODESEGMENT))
Kevin O'Connor4cd522e2013-11-29 12:14:34 -050049 return;
50 // setup for serial logging: 8N1
51 u8 oldparam, newparam = 0x03;
Ricardo Ribalda Delgado93329652016-12-20 19:03:58 +010052 oldparam = serial_debug_read(SEROFF_LCR);
53 serial_debug_write(SEROFF_LCR, newparam);
Kevin O'Connor4cd522e2013-11-29 12:14:34 -050054 // Disable irqs
55 u8 oldier, newier = 0;
Ricardo Ribalda Delgado93329652016-12-20 19:03:58 +010056 oldier = serial_debug_read(SEROFF_IER);
57 serial_debug_write(SEROFF_IER, newier);
Kevin O'Connor4cd522e2013-11-29 12:14:34 -050058
59 if (oldparam != newparam || oldier != newier)
60 dprintf(1, "Changing serial settings was %x/%x now %x/%x\n"
61 , oldparam, oldier, newparam, newier);
62}
63
64// Write a character to the serial port.
65static void
66serial_debug(char c)
67{
Ricardo Ribalda Delgado93329652016-12-20 19:03:58 +010068 if (!CONFIG_DEBUG_SERIAL && (!CONFIG_DEBUG_SERIAL_MMIO || MODESEGMENT))
Kevin O'Connor4cd522e2013-11-29 12:14:34 -050069 return;
70 int timeout = DEBUG_TIMEOUT;
Ricardo Ribalda Delgado93329652016-12-20 19:03:58 +010071 while ((serial_debug_read(SEROFF_LSR) & 0x20) != 0x20)
Kevin O'Connor4cd522e2013-11-29 12:14:34 -050072 if (!timeout--)
73 // Ran out of time.
74 return;
Ricardo Ribalda Delgado93329652016-12-20 19:03:58 +010075 serial_debug_write(SEROFF_DATA, c);
Kevin O'Connor4cd522e2013-11-29 12:14:34 -050076}
77
78void
79serial_debug_putc(char c)
80{
81 if (c == '\n')
82 serial_debug('\r');
83 serial_debug(c);
84}
85
86// Make sure all serial port writes have been completely sent.
87void
88serial_debug_flush(void)
89{
Ricardo Ribalda Delgado93329652016-12-20 19:03:58 +010090 if (!CONFIG_DEBUG_SERIAL && (!CONFIG_DEBUG_SERIAL_MMIO || MODESEGMENT))
Kevin O'Connor4cd522e2013-11-29 12:14:34 -050091 return;
92 int timeout = DEBUG_TIMEOUT;
Ricardo Ribalda Delgado93329652016-12-20 19:03:58 +010093 while ((serial_debug_read(SEROFF_LSR) & 0x60) != 0x60)
Kevin O'Connor4cd522e2013-11-29 12:14:34 -050094 if (!timeout--)
95 // Ran out of time.
96 return;
97}
98
99
100/****************************************************************
101 * QEMU debug port
102 ****************************************************************/
103
104u16 DebugOutputPort VARFSEG = 0x402;
105
106// Write a character to the special debugging port.
107void
108qemu_debug_putc(char c)
109{
110 if (CONFIG_DEBUG_IO && runningOnQEMU())
111 // Send character to debug port.
112 outb(c, GET_GLOBAL(DebugOutputPort));
113}