1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/* Copyright 2021 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <kernel.h>
#include <zephyr.h>
#include "common.h"
#include "console.h"
#include "ec_commands.h"
static char console_buf[CONFIG_PLATFORM_EC_HOSTCMD_CONSOLE_BUF_SIZE];
static uint32_t previous_snapshot_idx;
static uint32_t current_snapshot_idx;
static uint32_t tail_idx;
static inline uint32_t next_idx(uint32_t cur_idx)
{
return (cur_idx + 1) % ARRAY_SIZE(console_buf);
}
K_MUTEX_DEFINE(console_write_lock);
void console_buf_notify_chars(const char *s, size_t len)
{
/*
* This is just notifying of console characters for debugging
* output, so if we are unable to lock the mutex immediately,
* then just drop the string.
*/
if (k_mutex_lock(&console_write_lock, K_NO_WAIT))
return;
/* We got the mutex. */
while (len--) {
/* Don't copy null byte into buffer */
if (!(*s))
continue;
uint32_t new_tail = next_idx(tail_idx);
/* Check if we are starting to overwrite our snapshot
* heads
*/
if (new_tail == previous_snapshot_idx)
previous_snapshot_idx =
next_idx(previous_snapshot_idx);
if (new_tail == current_snapshot_idx)
current_snapshot_idx =
next_idx(current_snapshot_idx);
console_buf[new_tail] = *s++;
tail_idx = new_tail;
}
k_mutex_unlock(&console_write_lock);
}
enum ec_status uart_console_read_buffer_init(void)
{
if (k_mutex_lock(&console_write_lock, K_MSEC(100)))
/* Failed to acquire console buffer mutex */
return EC_RES_TIMEOUT;
previous_snapshot_idx = current_snapshot_idx;
current_snapshot_idx = tail_idx;
k_mutex_unlock(&console_write_lock);
return EC_RES_SUCCESS;
}
int uart_console_read_buffer(uint8_t type, char *dest, uint16_t dest_size,
uint16_t *write_count_out)
{
uint32_t *head;
uint16_t write_count = 0;
switch (type) {
case CONSOLE_READ_NEXT:
/* Start from beginning of latest snapshot */
head = ¤t_snapshot_idx;
break;
case CONSOLE_READ_RECENT:
/* Start from end of previous snapshot */
head = &previous_snapshot_idx;
break;
default:
return EC_RES_INVALID_PARAM;
}
/* We need to make sure we have room for at least the null byte */
if (dest_size == 0)
return EC_RES_INVALID_PARAM;
if (k_mutex_lock(&console_write_lock, K_MSEC(100)))
/* Failed to acquire console buffer mutex */
return EC_RES_TIMEOUT;
if (*head == tail_idx) {
/* No new data, return empty response */
k_mutex_unlock(&console_write_lock);
return EC_RES_SUCCESS;
}
do {
if (write_count >= dest_size - 1)
/* Buffer is full, minus the space for a null byte */
break;
dest[write_count] = console_buf[*head];
write_count++;
*head = next_idx(*head);
} while (*head != tail_idx);
dest[write_count] = '\0';
write_count++;
*write_count_out = write_count;
k_mutex_unlock(&console_write_lock);
return EC_RES_SUCCESS;
}
/* ECOS uart buffer, putc is blocking instead. */
int uart_buffer_full(void)
{
return false;
}
|