Xen Test Framework
console.c
Go to the documentation of this file.
1#include <xtf/types.h>
2#include <xtf/atomic.h>
3#include <xtf/bitops.h>
4#include <xtf/console.h>
5#include <xtf/hypercall.h>
6#include <xtf/lib.h>
7#include <xtf/libc.h>
8#include <xtf/traps.h>
9
10/*
11 * Output functions, registered if/when available.
12 * Possibilities:
13 * - Xen hypervisor console
14 * - PV console
15 * - Qemu debug console
16 */
18static unsigned int nr_cons_cb;
19
20/* Guest PV console details. */
23
25{
27 output_fns[nr_cons_cb++] = fn;
28 else
29 panic("Too many console callbacks\n");
30}
31
32/*
33 * Write some data into the pv ring, taking care not to overflow the ring.
34 */
35static size_t pv_console_write_some(const char *buf, size_t len)
36{
37 size_t s = 0;
39
40 while ( (s < len) && ((prod - cons) < sizeof(pv_ring->out)) )
41 pv_ring->out[prod++ & (sizeof(pv_ring->out) - 1)] = buf[s++];
42
44
45 return s;
46}
47
48/*
49 * Read out data from the pv ring, either until buffer is filled or no
50 * more data are available. Might result in partial strings, depending
51 * on how xenconsoled passes in data.
52 *
53 * Will block if no data are available.
54 */
55size_t pv_console_read_some(char *buf, size_t len)
56{
57 size_t s = 0;
58 uint32_t cons, prod;
59
63
64 cons = pv_ring->in_cons;
66
67 while ( (s < len) && (0 < (prod - cons)) )
68 buf[s++] = pv_ring->in[cons++ & (sizeof(pv_ring->in) - 1)];
69
71
72 return s;
73}
74
75/*
76 * Write some data into the pv ring, synchronously waiting for all data to be
77 * consumed.
78 */
79static void pv_console_write(const char *buf, size_t len)
80{
81 size_t written = 0;
83
84 do
85 {
86 /* Try and put some data into the ring. */
87 written = pv_console_write_some(&buf[written], len - written);
88
89 /* Kick xenconsoled into action. */
91
92 /*
93 * If we have more to write, the ring must have filled up. Wait for
94 * more space.
95 */
96 if ( written < len )
97 {
98 while ( ACCESS_ONCE(pv_ring->out_cons) == cons )
100 }
101
102 } while ( written < len );
103
104 /* Wait for xenconsoled to consume all the data we gave. */
107}
108
110{
111 if ( port >= (sizeof(shared_info.evtchn_pending) * CHAR_BIT) )
112 panic("evtchn %u out of evtchn_pending[] range\n", port);
113
114 pv_ring = ring;
115 pv_evtchn = port;
117}
118
119void vprintk(const char *fmt, va_list args)
120{
121 static char buf[2048];
122 unsigned int i;
123 int rc;
124
125 rc = vsnprintf_internal(buf, sizeof(buf), fmt, args, LF_TO_CRLF);
126
127 if ( rc > (int)sizeof(buf) )
128 panic("vprintk() buffer overflow\n");
129
130 for ( i = 0; i < nr_cons_cb; ++i )
131 output_fns[i](buf, rc);
132}
133
134void printk(const char *fmt, ...)
135{
136 va_list args;
137
138 va_start(args, fmt);
139 vprintk(fmt, args);
140 va_end(args);
141}
142
143/*
144 * Local variables:
145 * mode: C
146 * c-file-style: "BSD"
147 * c-basic-offset: 4
148 * tab-width: 4
149 * indent-tabs-mode: nil
150 * End:
151 */
static bool test_and_clear_bit(unsigned int bit, volatile void *addr)
Definition: bitops.h:53
#define LOAD_ACQUIRE(p)
Definition: atomic.h:7
#define STORE_RELEASE(p, v)
Definition: atomic.h:13
void vprintk(const char *fmt, va_list args)
Definition: console.c:119
void printk(const char *fmt,...)
Definition: console.c:134
static evtchn_port_t pv_evtchn
Definition: console.c:22
static void pv_console_write(const char *buf, size_t len)
Definition: console.c:79
void register_console_callback(cons_output_cb fn)
Definition: console.c:24
static size_t pv_console_write_some(const char *buf, size_t len)
Definition: console.c:35
static cons_output_cb output_fns[3]
Definition: console.c:17
static xencons_interface_t * pv_ring
Definition: console.c:21
size_t pv_console_read_some(char *buf, size_t len)
Definition: console.c:55
static unsigned int nr_cons_cb
Definition: console.c:18
void init_pv_console(xencons_interface_t *ring, evtchn_port_t port)
Definition: console.c:109
uint32_t evtchn_port_t
Definition: event_channel.h:11
static int hypercall_evtchn_send(evtchn_port_t port)
Definition: hypercall.h:223
static long hypercall_poll(evtchn_port_t port)
Definition: hypercall.h:211
static void hypercall_yield(void)
Definition: hypercall.h:206
Low level bit operations.
#define ACCESS_ONCE(x)
Definition: lib.h:10
#define ARRAY_SIZE(a)
Definition: lib.h:8
void panic(const char *fmt,...)
Definition: lib.c:15
#define LF_TO_CRLF
Definition: libc.h:48
#define CHAR_BIT
Definition: limits.h:9
#define va_end(v)
Definition: stdarg.h:11
#define va_start(v, l)
Definition: stdarg.h:10
__builtin_va_list va_list
Definition: stdarg.h:9
__UINT32_TYPE__ uint32_t
Definition: stdint.h:16
unsigned long evtchn_pending[sizeof(unsigned long) *8]
Definition: xen.h:186
uint32_t in_prod
Definition: console.h:8
uint32_t in_cons
Definition: console.h:8
uint32_t out_cons
Definition: console.h:9
char in[1024]
Definition: console.h:6
uint32_t out_prod
Definition: console.h:9
char out[2048]
Definition: console.h:7
Common declarations for all tests.
int vsnprintf_internal(char *buf, size_t size, const char *fmt, va_list args, unsigned int caller_flags)
Definition: vsnprintf.c:276
void(* cons_output_cb)(const char *buf, size_t len)
Definition: console.h:11