1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13/*-
14 * Copyright (c) 2015 Martin Lucina.  All Rights Reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 *    notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 *    notice, this list of conditions and the following disclaimer in the
23 *    documentation and/or other materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37
38#include <bmk-core/types.h>
39#include <sel4/kernel.h>
40#include <sel4/helpers.h>
41
42#include <bmk-core/printf.h>
43
44#include <stdio.h>
45#include <arch_stdio.h>
46
47void debug_putchar(int c);
48static void (*vcons_putc)(int) = debug_putchar;
49static void (*vcons_flush)(void) = NULL;
50
51/* context for talking to the serial server */
52static serial_client_context_t context;
53/* index in the shared buffer we have buffered up to */
54static ssize_t shmem_index = -1;
55
56static void cons_flush(void)
57{
58    serial_server_flush(&context, shmem_index);
59    shmem_index = 0;
60}
61
62void cons_putc(int c)
63{
64    assert(shmem_index < context.shmem_size);
65    assert(shmem_index > -1);
66
67    context.shmem[shmem_index] = c;
68    shmem_index++;
69
70    if (c == '\n' || shmem_index == context.shmem_size) {
71        cons_flush();
72    }
73}
74
75void debug_putchar(int c) {
76#ifdef CONFIG_DEBUG_BUILD
77    seL4_DebugPutChar(c);
78#endif
79}
80
81static size_t cons_write(void* data, size_t count) {
82    for (int i = 0; i < count; i++) {
83        vcons_putc(((char*)data)[i]);
84    }
85    return count;
86}
87
88void cons_init(void)
89{
90    if (env.custom_simple.serial_config.serial != SERIAL_SERVER) {
91        vcons_putc = env.custom_simple.serial_config.putchar;
92        /* no flush */
93    } else {
94        int error = serial_server_client_connect(env.custom_simple.serial_config.ep,
95                                                 &env.vka, &env.vspace, &context);
96        if (!error) {
97            vcons_putc = cons_putc;
98            vcons_flush = cons_flush;
99            shmem_index = 0;
100        }
101    }
102    sel4muslcsys_register_stdio_write_fn(cons_write);
103    bmk_printf_init(vcons_putc, vcons_flush);
104}
105
106