1 /* $NetBSD: consinit.c,v 1.5 2024/02/02 22:33:42 andvar Exp $ */
2 /*
3 * Copyright (c) 2009 KIYOHARA Takashi
4 * All rights reserved.
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
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27 #include <sys/cdefs.h>
28 __KERNEL_RCSID(0, "$NetBSD: consinit.c,v 1.5 2024/02/02 22:33:42 andvar Exp $");
29
30 #include <sys/param.h>
31 #include <sys/device.h>
32 #include <sys/termios.h>
33
34 #include <machine/bus.h>
35 #include <machine/dig64.h>
36 #include <machine/md_var.h>
37
38 #include <dev/acpi/acpica.h>
39
40 #include "com.h"
41 #include "vga.h"
42 #include "ssccons.h"
43
44 #include <dev/cons.h>
45 #if NCOM > 0
46 #include <dev/ic/comvar.h>
47 #endif
48 #if NVGA > 0
49 #include <dev/ic/vgareg.h>
50 #include <dev/ic/vgavar.h>
51 #endif
52
53
54 static void pcdp_cnprobe(struct consdev *);
55 static void pcdp_cninit(struct consdev *);
56
57 cons_decl(ssc);
58
59 struct consdev constab[] = {
60 { pcdp_cnprobe, pcdp_cninit,
61 NULL, NULL, NULL, NULL, NULL, NULL, NODEV, CN_DEAD },
62 #if NSSCCONS > 0
63 cons_init(ssc),
64 #endif
65 { NULL }
66 };
67
68
69 void
consinit(void)70 consinit(void)
71 {
72
73 cninit();
74 }
75
76 static void
pcdp_cnprobe(struct consdev * cn)77 pcdp_cnprobe(struct consdev *cn)
78 {
79 struct dig64_hcdp_table *tbl;
80 union dev_desc *desc;
81 uint64_t hcdp;
82 int n, m;
83
84 hcdp = ia64_get_hcdp();
85 if (hcdp != 0) {
86 tbl = (void*)IA64_PHYS_TO_RR7(hcdp);
87 n = 0;
88 m = tbl->length - sizeof(struct dig64_hcdp_table);
89 while (n < m) {
90 desc = (union dev_desc *)((char *)tbl->entry + n);
91 #if NVGA > 0
92 if (devdesc->type ==
93 (DIG64_ENTRYTYPE_VGA | DIG64_ENTRYTYPE_OUTONLY)) {
94 #if defined(DIAGNOSTIC)
95 if (tbl->revision < 3)
96 panic("PCDP found in HCDP rev.%d."
97 " Maybe unsupported PCDP",
98 tbl->revision);
99 #endif
100 cn->cn_pri = CN_NORMAL;
101 break;
102 }
103 #endif
104 #if NCOM > 0
105 if (desc->type == DIG64_HCDP_CONSOLE) {
106 cn->cn_pri = CN_REMOTE;
107 break;
108 }
109 #endif
110
111 if (desc->type == DIG64_ENTRYTYPE_TYPE0 ||
112 desc->type == DIG64_ENTRYTYPE_TYPE1)
113 n += sizeof(struct dig64_hcdp_entry);
114 else
115 n += desc->pcdp.length;
116 }
117 }
118 if (cn->cn_pri != CN_DEAD)
119 cn->cn_dev = ~NODEV; /* Shall we makedev()? */
120 }
121
122 static void
pcdp_cninit(struct consdev * cn)123 pcdp_cninit(struct consdev *cn)
124 {
125 struct dig64_hcdp_table *tbl;
126 #if NVGA > 0 || NCOM > 0
127 union dev_desc *desc;
128 #endif
129 uint64_t hcdp;
130 int n, m;
131
132 hcdp = ia64_get_hcdp();
133 if (hcdp == 0)
134 panic("lost console...\n");
135
136 tbl = (void *)IA64_PHYS_TO_RR7(hcdp);
137 n = 0;
138 m = tbl->length - sizeof(struct dig64_hcdp_table);
139 while (n < m) {
140 #if NVGA > 0 || NCOM > 0
141 desc = (union dev_desc *)((char *)tbl->entry + n);
142 #endif
143
144 /* not yet... */
145 /* Our VGA is Framebuffer? */
146 #if NVGA > 0
147 if (cn->cn_pri == CN_NORMAL &&
148 desc->type ==
149 (DIG64_ENTRYTYPE_VGA | DIG64_ENTRYTYPE_OUTONLY)) {
150 struct dig64_pcdp_entry *ent = &desc->pcdp;
151
152 if (ent->specs.type == DIG64_PCDP_SPEC_PCI) {
153 struct dig64_pci_spec *spec = ent->specs.pci;
154
155 if (spec->flags & DIG64_FLAGS_MMIO_TRA_VALID)
156 (void*)spec->mmio_tra;
157 if (spec->flags & DIG64_FLAGS_IOPORT_TRA_VALID)
158 (void*)spec->ioport_tra;
159 }
160
161 break;
162 }
163 #endif
164 #if NCOM > 0
165 if (cn->cn_pri == CN_REMOTE &&
166 desc->type == DIG64_HCDP_CONSOLE) {
167 struct dig64_hcdp_entry *ent = &desc->uart;
168 bus_addr_t ioaddr;
169 bus_space_tag_t iot;
170 const uint64_t rate =
171 ((uint64_t)ent->baud_high << 32) | ent->baud_low;
172 tcflag_t cflag =
173 TTYDEF_CFLAG & ~(CSIZE | PARENB | PARODD);
174
175 switch (ent->databits) {
176 case 5:
177 cflag = CS5;
178 break;
179 case 6:
180 cflag = CS6;
181 break;
182 case 7:
183 cflag = CS7;
184 break;
185 case 8:
186 cflag = CS8;
187 break;
188 default:
189 panic("unsupported databits %d\n",
190 ent->databits);
191 }
192 switch (ent->parity) {
193 case DIG64_HCDP_PARITY_NO:
194 break;
195 case DIG64_HCDP_PARITY_ODD:
196 cflag |= PARODD;
197
198 /* FALLTHROUGH */
199
200 case DIG64_HCDP_PARITY_EVEN:
201 cflag |= PARENB;
202 break;
203 case DIG64_HCDP_PARITY_MARK:
204 case DIG64_HCDP_PARITY_SPACE:
205 default:
206 panic("unsupported parity type %d\n",
207 ent->parity);
208 }
209 if (ent->stopbits == DIG64_HCDP_STOPBITS_1)
210 cflag &= ~CSTOPB;
211 else if (ent->stopbits == DIG64_HCDP_STOPBITS_2)
212 cflag |= CSTOPB;
213 else
214 panic("unsupported stopbits type %d\n",
215 ent->stopbits);
216 iot = (ent->address.addr_space ==
217 ACPI_ADR_SPACE_SYSTEM_MEMORY) ?
218 IA64_BUS_SPACE_MEM : IA64_BUS_SPACE_IO;
219 ioaddr = ((uint64_t)ent->address.addr_high << 32) |
220 ent->address.addr_low;
221 comcnattach(iot, ioaddr, rate,
222 (ent->pclock != 0) ? ent->pclock : COM_FREQ,
223 COM_TYPE_NORMAL, cflag);
224 break;
225 }
226 #endif
227 }
228 }
229