blob: 51fd871dff9b3fbfd939ac4cd6d54c88bb01502f [file] [log] [blame]
Simon Glass7accb6e2011-10-03 19:26:46 +00001/*
2 * Copyright (c) 2011 The Chromium OS Authors.
Simon Glass7accb6e2011-10-03 19:26:46 +00003 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02004 * SPDX-License-Identifier: GPL-2.0+
Simon Glass7accb6e2011-10-03 19:26:46 +00005 */
6
7/*
8 * This provide a test serial port. It provides an emulated serial port where
9 * a test program and read out the serial output and inject serial input for
10 * U-Boot.
11 */
12
13#include <common.h>
Simon Glass7d95f2a2014-02-27 13:26:19 -070014#include <lcd.h>
Simon Glass7accb6e2011-10-03 19:26:46 +000015#include <os.h>
Marek Vasutcef46b72012-09-14 22:33:21 +020016#include <serial.h>
17#include <linux/compiler.h>
Simon Glassffb87902014-02-27 13:26:22 -070018#include <asm/state.h>
Simon Glass7accb6e2011-10-03 19:26:46 +000019
Taylor Hutte1015502013-02-24 17:33:13 +000020/*
21 *
22 * serial_buf: A buffer that holds keyboard characters for the
23 * Sandbox U-boot.
24 *
25 * invariants:
26 * serial_buf_write == serial_buf_read -> empty buffer
27 * (serial_buf_write + 1) % 16 == serial_buf_read -> full buffer
28 */
29static char serial_buf[16];
30static unsigned int serial_buf_write;
31static unsigned int serial_buf_read;
32
Marek Vasutcef46b72012-09-14 22:33:21 +020033static int sandbox_serial_init(void)
Simon Glass7accb6e2011-10-03 19:26:46 +000034{
Simon Glassffb87902014-02-27 13:26:22 -070035 struct sandbox_state *state = state_get_current();
36
37 if (state->term_raw != STATE_TERM_COOKED)
38 os_tty_raw(0, state->term_raw == STATE_TERM_RAW_WITH_SIGS);
Simon Glass7accb6e2011-10-03 19:26:46 +000039 return 0;
40}
41
Marek Vasutcef46b72012-09-14 22:33:21 +020042static void sandbox_serial_setbrg(void)
Simon Glass7accb6e2011-10-03 19:26:46 +000043{
44}
45
Marek Vasutcef46b72012-09-14 22:33:21 +020046static void sandbox_serial_putc(const char ch)
Simon Glass7accb6e2011-10-03 19:26:46 +000047{
48 os_write(1, &ch, 1);
49}
50
Marek Vasutcef46b72012-09-14 22:33:21 +020051static void sandbox_serial_puts(const char *str)
Simon Glass7accb6e2011-10-03 19:26:46 +000052{
Mike Frysinger5778d542011-10-26 00:20:39 +000053 os_write(1, str, strlen(str));
Simon Glass7accb6e2011-10-03 19:26:46 +000054}
55
Taylor Hutte1015502013-02-24 17:33:13 +000056static unsigned int increment_buffer_index(unsigned int index)
Simon Glass7accb6e2011-10-03 19:26:46 +000057{
Taylor Hutte1015502013-02-24 17:33:13 +000058 return (index + 1) % ARRAY_SIZE(serial_buf);
Simon Glass7accb6e2011-10-03 19:26:46 +000059}
60
Marek Vasutcef46b72012-09-14 22:33:21 +020061static int sandbox_serial_tstc(void)
Simon Glass7accb6e2011-10-03 19:26:46 +000062{
Taylor Hutte1015502013-02-24 17:33:13 +000063 const unsigned int next_index =
64 increment_buffer_index(serial_buf_write);
65 ssize_t count;
66
67 os_usleep(100);
Simon Glass7d95f2a2014-02-27 13:26:19 -070068#ifdef CONFIG_LCD
69 lcd_sync();
70#endif
Taylor Hutte1015502013-02-24 17:33:13 +000071 if (next_index == serial_buf_read)
72 return 1; /* buffer full */
73
74 count = os_read_no_block(0, &serial_buf[serial_buf_write], 1);
75 if (count == 1)
76 serial_buf_write = next_index;
77 return serial_buf_write != serial_buf_read;
78}
79
80static int sandbox_serial_getc(void)
81{
82 int result;
83
84 while (!sandbox_serial_tstc())
85 ; /* buffer empty */
86
87 result = serial_buf[serial_buf_read];
88 serial_buf_read = increment_buffer_index(serial_buf_read);
89 return result;
Simon Glass7accb6e2011-10-03 19:26:46 +000090}
Marek Vasutcef46b72012-09-14 22:33:21 +020091
Marek Vasutcef46b72012-09-14 22:33:21 +020092static struct serial_device sandbox_serial_drv = {
93 .name = "sandbox_serial",
94 .start = sandbox_serial_init,
95 .stop = NULL,
96 .setbrg = sandbox_serial_setbrg,
97 .putc = sandbox_serial_putc,
98 .puts = sandbox_serial_puts,
99 .getc = sandbox_serial_getc,
100 .tstc = sandbox_serial_tstc,
101};
102
103void sandbox_serial_initialize(void)
104{
105 serial_register(&sandbox_serial_drv);
106}
107
108__weak struct serial_device *default_serial_console(void)
109{
110 return &sandbox_serial_drv;
111}