]>
Commit | Line | Data |
---|---|---|
7accb6ea SG |
1 | /* |
2 | * Copyright (c) 2011 The Chromium OS Authors. | |
7accb6ea | 3 | * |
1a459660 | 4 | * SPDX-License-Identifier: GPL-2.0+ |
7accb6ea SG |
5 | */ |
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> | |
14 | #include <os.h> | |
cef46b77 MV |
15 | #include <serial.h> |
16 | #include <linux/compiler.h> | |
7accb6ea | 17 | |
e101550a TH |
18 | /* |
19 | * | |
20 | * serial_buf: A buffer that holds keyboard characters for the | |
21 | * Sandbox U-boot. | |
22 | * | |
23 | * invariants: | |
24 | * serial_buf_write == serial_buf_read -> empty buffer | |
25 | * (serial_buf_write + 1) % 16 == serial_buf_read -> full buffer | |
26 | */ | |
27 | static char serial_buf[16]; | |
28 | static unsigned int serial_buf_write; | |
29 | static unsigned int serial_buf_read; | |
30 | ||
cef46b77 | 31 | static int sandbox_serial_init(void) |
7accb6ea | 32 | { |
ab06a758 | 33 | os_tty_raw(0); |
7accb6ea SG |
34 | return 0; |
35 | } | |
36 | ||
cef46b77 | 37 | static void sandbox_serial_setbrg(void) |
7accb6ea SG |
38 | { |
39 | } | |
40 | ||
cef46b77 | 41 | static void sandbox_serial_putc(const char ch) |
7accb6ea SG |
42 | { |
43 | os_write(1, &ch, 1); | |
44 | } | |
45 | ||
cef46b77 | 46 | static void sandbox_serial_puts(const char *str) |
7accb6ea | 47 | { |
5778d54a | 48 | os_write(1, str, strlen(str)); |
7accb6ea SG |
49 | } |
50 | ||
e101550a TH |
51 | static unsigned int increment_buffer_index(unsigned int index) |
52 | { | |
53 | return (index + 1) % ARRAY_SIZE(serial_buf); | |
54 | } | |
55 | ||
56 | static int sandbox_serial_tstc(void) | |
7accb6ea | 57 | { |
e101550a TH |
58 | const unsigned int next_index = |
59 | increment_buffer_index(serial_buf_write); | |
ec8f0b90 | 60 | ssize_t count; |
7accb6ea | 61 | |
e101550a TH |
62 | os_usleep(100); |
63 | if (next_index == serial_buf_read) | |
64 | return 1; /* buffer full */ | |
65 | ||
66 | count = os_read_no_block(0, &serial_buf[serial_buf_write], 1); | |
67 | if (count == 1) | |
68 | serial_buf_write = next_index; | |
69 | return serial_buf_write != serial_buf_read; | |
7accb6ea SG |
70 | } |
71 | ||
e101550a | 72 | static int sandbox_serial_getc(void) |
7accb6ea | 73 | { |
e101550a TH |
74 | int result; |
75 | ||
76 | while (!sandbox_serial_tstc()) | |
77 | ; /* buffer empty */ | |
78 | ||
79 | result = serial_buf[serial_buf_read]; | |
80 | serial_buf_read = increment_buffer_index(serial_buf_read); | |
81 | return result; | |
7accb6ea | 82 | } |
cef46b77 | 83 | |
cef46b77 MV |
84 | static struct serial_device sandbox_serial_drv = { |
85 | .name = "sandbox_serial", | |
86 | .start = sandbox_serial_init, | |
87 | .stop = NULL, | |
88 | .setbrg = sandbox_serial_setbrg, | |
89 | .putc = sandbox_serial_putc, | |
90 | .puts = sandbox_serial_puts, | |
91 | .getc = sandbox_serial_getc, | |
92 | .tstc = sandbox_serial_tstc, | |
93 | }; | |
94 | ||
95 | void sandbox_serial_initialize(void) | |
96 | { | |
97 | serial_register(&sandbox_serial_drv); | |
98 | } | |
99 | ||
100 | __weak struct serial_device *default_serial_console(void) | |
101 | { | |
102 | return &sandbox_serial_drv; | |
103 | } |