1 /*
2 * Copyright 2014, General Dynamics C4 Systems
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7 #pragma once
8
9 #include <config.h>
10
11 #ifdef CONFIG_DEBUG_BUILD
12 /* io for dumping capdl */
13 unsigned char kernel_getDebugChar(void);
14 #endif
15
16
17 #ifdef CONFIG_PRINTING
18
19 #include <arch/types.h>
20 #include <stdarg.h>
21
22 /* the actual output function */
23 void kernel_putDebugChar(unsigned char c);
24
25 /* This is the actual implementation of the kernel printing API. It must never
26 * be called directly from anywhere except the function defined in this file.
27 */
28 int impl_kvprintf(const char *format, va_list ap);
29 int impl_ksnvprintf(char *str, word_t size, const char *format, va_list ap);
30
31 /*
32 *------------------------------------------------------------------------------
33 * Kernel printing API
34 *------------------------------------------------------------------------------
35 */
36
37 /* Writes a character to the kernel output channel. This is used to implement
38 * the syscall SysDebugPutChar.
39 */
kernel_putchar(char c)40 static inline void kernel_putchar(
41 char c)
42 {
43 /* Write to target specific debug output channel. */
44 kernel_putDebugChar(c);
45 }
46
47 /* Writes a character to the active output channel. This is used by all code
48 * related to printf(). Contrary to the common signature of putchar(), there is
49 * no return value here.
50 */
putchar(char c)51 static inline void putchar(
52 char c)
53 {
54 /* Write to target specific debug output channel. Purposely, we do not call
55 * kernel_putchar() here, as the kernel printf() channel is semantically
56 * different from the syscall SysDebugPutChar channel. The unification
57 * of both channels happens at the lower layer eventually
58 */
59 kernel_putDebugChar(c);
60 }
61
62 /* Writes the string and a trailing newline. There is no point to enforce a
63 * kernel_puts(), as this is just a wrapper for putchar() anyway.
64 */
puts(const char * str)65 static inline int puts(
66 const char *str)
67 {
68 if (str) {
69 while (*str) {
70 putchar(*str++);
71 }
72 }
73 putchar('\n');
74 /* Standards define that a non-negative number is returned on success. */
75 return 0;
76 }
77
78 /* There should only be a kprintf() that all kernel code must use for printing,
79 * but for convenience we provide a printf() here.
80 */
printf(const char * format,...)81 static inline __attribute__((format(printf, 1, 2))) int printf(
82 const char *format,
83 ...)
84 {
85 va_list args;
86 va_start(args, format);
87 int ret = impl_kvprintf(format, args); /* will call putchar() eventually */
88 va_end(args);
89 return ret;
90 }
91
92 /* Provide the standard snprintf() for write formatted data into a buffer, which
93 * can then be printed or stored.
94 */
snprintf(char * buf,word_t size,const char * format,...)95 static inline __attribute__((format(printf, 3, 4))) int snprintf(
96 char *buf,
97 word_t size,
98 const char *format,
99 ...)
100 {
101 va_list args;
102 va_start(args, format);
103 int ret = impl_ksnvprintf(buf, size, format, args);
104 va_end(args);
105 return ret;
106 }
107
108 #else /* not CONFIG_PRINTING */
109
110 /* The verification runs on the output of the preprocessing stage of a release
111 * build configuration, CONFIG_PRINTING is not enabled there. We remove all
112 * calls to printf() completely from the code base, because neither printf() nor
113 * the usage of a variable argument list is supported by the verification
114 * toolchain. It would just reject the code if it encounters any unsupported
115 * things.
116 */
117 #define printf(...) ((void)(0))
118
119 /* Seems there is no need to define out these functions, they are use by code
120 * that is active with CONFIG_PRINTING only.
121 *
122 * #define kernel_putchar(...) ((void)(0))
123 * #define putchar(...) ((void)(0))
124 * #define puts(...) ((void)(0))
125 * #define snprintf(...) ((void)(0))
126 */
127
128 #endif /* [not] CONFIG_PRINTING */
129