]>
Commit | Line | Data |
---|---|---|
056a1eb7 SF |
1 | /* $Id: logcom.cpp $ */ |
2 | /** @file | |
3 | * IPRT - Logging to Serial Port. | |
4 | */ | |
5 | ||
6 | /* | |
6d209b23 | 7 | * Copyright (C) 2006-2017 Oracle Corporation |
056a1eb7 SF |
8 | * |
9 | * This file is part of VirtualBox Open Source Edition (OSE), as | |
10 | * available from http://www.virtualbox.org. This file is free software; | |
11 | * you can redistribute it and/or modify it under the terms of the GNU | |
12 | * General Public License (GPL) as published by the Free Software | |
13 | * Foundation, in version 2 as it comes in the "COPYING" file of the | |
14 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the | |
15 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. | |
16 | * | |
17 | * The contents of this file may alternatively be used under the terms | |
18 | * of the Common Development and Distribution License Version 1.0 | |
19 | * (CDDL) only, as it comes in the "COPYING.CDDL" file of the | |
20 | * VirtualBox OSE distribution, in which case the provisions of the | |
21 | * CDDL are applicable instead of those of the GPL. | |
22 | * | |
23 | * You may elect to license modified versions of this file under the | |
24 | * terms and conditions of either the GPL or the CDDL or both. | |
25 | */ | |
26 | ||
27 | ||
28 | /********************************************************************************************************************************* | |
29 | * Defined Constants And Macros * | |
30 | *********************************************************************************************************************************/ | |
31 | #ifndef IPRT_UART_BASE | |
32 | /** The port address of the COM port to log to. | |
33 | * | |
34 | * To override the default (COM1) append IPRT_UART_BASE=0xWXYZ to DEFS in your | |
35 | * LocalConfig.kmk. Alternatively you can edit this file, but the don't forget | |
36 | * to also update the default found in VBox/asmdefs.h. | |
37 | * | |
38 | * Standard port assignments are: COM1=0x3f8, COM2=0x2f8, COM3=0x3e8, COM4=0x2e8. | |
39 | */ | |
40 | # define IPRT_UART_BASE 0x3f8 | |
41 | #endif | |
42 | ||
43 | ||
44 | /********************************************************************************************************************************* | |
45 | * Header Files * | |
46 | *********************************************************************************************************************************/ | |
47 | #include <iprt/log.h> | |
48 | #include "internal/iprt.h" | |
49 | ||
50 | #include <iprt/asm.h> | |
51 | #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) /** @todo consider fixing the config instead. */ | |
52 | # include <iprt/asm-amd64-x86.h> | |
53 | #endif | |
54 | #include <iprt/stdarg.h> | |
55 | #include <iprt/string.h> | |
56 | ||
57 | ||
58 | /********************************************************************************************************************************* | |
59 | * Internal Functions * | |
60 | *********************************************************************************************************************************/ | |
61 | static DECLCALLBACK(size_t) rtLogComOutput(void *pv, const char *pachChars, size_t cbChars); | |
62 | ||
63 | ||
64 | /** | |
65 | * Prints a formatted string to the serial port used for logging. | |
66 | * | |
67 | * @returns Number of bytes written. | |
68 | * @param pszFormat Format string. | |
69 | * @param ... Optional arguments specified in the format string. | |
70 | */ | |
71 | RTDECL(size_t) RTLogComPrintf(const char *pszFormat, ...) | |
72 | { | |
73 | va_list args; | |
74 | size_t cb; | |
75 | va_start(args, pszFormat); | |
76 | cb = RTLogComPrintfV(pszFormat, args); | |
77 | va_end(args); | |
78 | ||
79 | return cb; | |
80 | } | |
81 | RT_EXPORT_SYMBOL(RTLogComPrintf); | |
82 | ||
83 | ||
84 | /** | |
85 | * Prints a formatted string to the serial port used for logging. | |
86 | * | |
87 | * @returns Number of bytes written. | |
88 | * @param pszFormat Format string. | |
89 | * @param args Optional arguments specified in the format string. | |
90 | */ | |
91 | RTDECL(size_t) RTLogComPrintfV(const char *pszFormat, va_list args) | |
92 | { | |
93 | return RTLogFormatV(rtLogComOutput, NULL, pszFormat, args); | |
94 | } | |
95 | RT_EXPORT_SYMBOL(RTLogComPrintfV); | |
96 | ||
97 | ||
98 | /** | |
99 | * Callback for RTLogFormatV which writes to the com port. | |
100 | * See PFNLOGOUTPUT() for details. | |
101 | */ | |
102 | static DECLCALLBACK(size_t) rtLogComOutput(void *pv, const char *pachChars, size_t cbChars) | |
103 | { | |
104 | NOREF(pv); | |
105 | if (cbChars) | |
106 | RTLogWriteCom(pachChars, cbChars); | |
107 | return cbChars; | |
108 | } | |
109 | ||
110 | ||
111 | /** | |
112 | * Write log buffer to COM port. | |
113 | * | |
114 | * @param pach Pointer to the buffer to write. | |
115 | * @param cb Number of bytes to write. | |
116 | */ | |
117 | RTDECL(void) RTLogWriteCom(const char *pach, size_t cb) | |
118 | { | |
119 | #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) | |
120 | const uint8_t *pu8; | |
121 | for (pu8 = (const uint8_t *)pach; cb-- > 0; pu8++) | |
122 | { | |
123 | register unsigned cMaxWait; | |
124 | register uint8_t u8; | |
125 | ||
126 | /* expand \n -> \r\n */ | |
127 | if (*pu8 == '\n') | |
128 | RTLogWriteCom("\r", 1); | |
129 | ||
130 | /* Check if port is ready. */ | |
131 | cMaxWait = ~0U; | |
132 | do | |
133 | { | |
134 | u8 = ASMInU8(IPRT_UART_BASE + 5); | |
135 | cMaxWait--; | |
136 | } while (!(u8 & 0x20) && u8 != 0xff && cMaxWait); | |
137 | ||
138 | /* write */ | |
139 | ASMOutU8(IPRT_UART_BASE, *pu8); | |
140 | } | |
141 | #else | |
142 | /* PORTME? */ | |
143 | #endif | |
144 | } | |
145 | RT_EXPORT_SYMBOL(RTLogWriteCom); | |
146 |