Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/powerpc/sysdev/udbg_memcons.c
26439 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* A udbg backend which logs messages and reads input from in memory
4
* buffers.
5
*
6
* The console output can be read from memcons_output which is a
7
* circular buffer whose next write position is stored in memcons.output_pos.
8
*
9
* Input may be passed by writing into the memcons_input buffer when it is
10
* empty. The input buffer is empty when both input_pos == input_start and
11
* *input_start == '\0'.
12
*
13
* Copyright (C) 2003-2005 Anton Blanchard and Milton Miller, IBM Corp
14
* Copyright (C) 2013 Alistair Popple, IBM Corp
15
*/
16
17
#include <linux/kernel.h>
18
#include <asm/barrier.h>
19
#include <asm/page.h>
20
#include <asm/processor.h>
21
#include <asm/udbg.h>
22
23
struct memcons {
24
char *output_start;
25
char *output_pos;
26
char *output_end;
27
char *input_start;
28
char *input_pos;
29
char *input_end;
30
};
31
32
static char memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE];
33
static char memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE];
34
35
struct memcons memcons = {
36
.output_start = memcons_output,
37
.output_pos = memcons_output,
38
.output_end = &memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE],
39
.input_start = memcons_input,
40
.input_pos = memcons_input,
41
.input_end = &memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE],
42
};
43
44
static void memcons_putc(char c)
45
{
46
char *new_output_pos;
47
48
*memcons.output_pos = c;
49
wmb();
50
new_output_pos = memcons.output_pos + 1;
51
if (new_output_pos >= memcons.output_end)
52
new_output_pos = memcons.output_start;
53
54
memcons.output_pos = new_output_pos;
55
}
56
57
static int memcons_getc_poll(void)
58
{
59
char c;
60
char *new_input_pos;
61
62
if (*memcons.input_pos) {
63
c = *memcons.input_pos;
64
65
new_input_pos = memcons.input_pos + 1;
66
if (new_input_pos >= memcons.input_end)
67
new_input_pos = memcons.input_start;
68
else if (*new_input_pos == '\0')
69
new_input_pos = memcons.input_start;
70
71
*memcons.input_pos = '\0';
72
wmb();
73
memcons.input_pos = new_input_pos;
74
return c;
75
}
76
77
return -1;
78
}
79
80
static int memcons_getc(void)
81
{
82
int c;
83
84
while (1) {
85
c = memcons_getc_poll();
86
if (c == -1)
87
cpu_relax();
88
else
89
break;
90
}
91
92
return c;
93
}
94
95
void __init udbg_init_memcons(void)
96
{
97
udbg_putc = memcons_putc;
98
udbg_getc = memcons_getc;
99
udbg_getc_poll = memcons_getc_poll;
100
}
101
102