Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/powerpc/pseries/phyp_dbg.c
39507 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (C) 2019 Leandro Lupori
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
*/
26
27
#include <sys/cdefs.h>
28
#include <sys/linker_set.h>
29
30
#include <dev/ofw/openfirm.h>
31
#include <gdb/gdb.h>
32
33
#include "phyp-hvcall.h"
34
35
static gdb_probe_f uart_phyp_dbg_probe;
36
static gdb_init_f uart_phyp_dbg_init;
37
static gdb_term_f uart_phyp_dbg_term;
38
static gdb_getc_f uart_phyp_dbg_getc;
39
static gdb_putc_f uart_phyp_dbg_putc;
40
41
GDB_DBGPORT(uart_phyp, uart_phyp_dbg_probe,
42
uart_phyp_dbg_init, uart_phyp_dbg_term,
43
uart_phyp_dbg_getc, uart_phyp_dbg_putc);
44
45
static struct uart_phyp_dbgport {
46
cell_t vtermid;
47
union {
48
uint64_t u64[2];
49
char str[16];
50
} inbuf;
51
uint64_t inbuflen;
52
} dbgport;
53
54
static int
55
uart_phyp_dbg_probe(void)
56
{
57
char buf[64];
58
cell_t reg;
59
phandle_t vty;
60
61
if (!getenv_string("hw.uart.dbgport", buf, sizeof(buf)))
62
return (-1);
63
64
if ((vty = OF_finddevice(buf)) == -1)
65
return (-1);
66
67
if (OF_getprop(vty, "name", buf, sizeof(buf)) <= 0)
68
return (-1);
69
if (strcmp(buf, "vty") != 0)
70
return (-1);
71
72
if (OF_getprop(vty, "device_type", buf, sizeof(buf)) == -1)
73
return (-1);
74
if (strcmp(buf, "serial") != 0)
75
return (-1);
76
77
if (OF_getprop(vty, "compatible", buf, sizeof(buf)) <= 0)
78
return (-1);
79
if (strcmp(buf, "hvterm1") != 0)
80
return (-1);
81
82
reg = ~0U;
83
OF_getencprop(vty, "reg", &reg, sizeof(reg));
84
if (reg == ~0U)
85
return (-1);
86
87
dbgport.vtermid = reg;
88
dbgport.inbuflen = 0;
89
90
return (0);
91
}
92
93
static void
94
uart_phyp_dbg_init(void)
95
{
96
}
97
98
static void
99
uart_phyp_dbg_term(void)
100
{
101
}
102
103
static int
104
uart_phyp_dbg_getc(void)
105
{
106
int c, err, next;
107
108
if (dbgport.inbuflen == 0) {
109
err = phyp_pft_hcall(H_GET_TERM_CHAR, dbgport.vtermid,
110
0, 0, 0, &dbgport.inbuflen, &dbgport.inbuf.u64[0],
111
&dbgport.inbuf.u64[1]);
112
if (err != H_SUCCESS)
113
return (-1);
114
}
115
116
if (dbgport.inbuflen == 0)
117
return (-1);
118
119
c = dbgport.inbuf.str[0];
120
dbgport.inbuflen--;
121
122
if (dbgport.inbuflen == 0)
123
return (c);
124
125
/*
126
* Since version 2.11.0, QEMU became bug-compatible
127
* with PowerVM's vty, by inserting a \0 after every \r.
128
* Filter it here.
129
*/
130
next = 1;
131
if (c == '\r' && dbgport.inbuf.str[next] == '\0') {
132
next++;
133
dbgport.inbuflen--;
134
}
135
136
if (dbgport.inbuflen > 0)
137
memmove(&dbgport.inbuf.str[0], &dbgport.inbuf.str[next],
138
dbgport.inbuflen);
139
140
return (c);
141
}
142
143
static void
144
uart_phyp_dbg_putc(int c)
145
{
146
int err;
147
148
union {
149
uint64_t u64;
150
unsigned char bytes[8];
151
} cbuf;
152
153
cbuf.bytes[0] = (unsigned char)c;
154
155
do {
156
err = phyp_hcall(H_PUT_TERM_CHAR, dbgport.vtermid, 1,
157
cbuf.u64, 0);
158
DELAY(100);
159
} while (err == H_BUSY);
160
}
161
162