xref: /netbsd-src/sys/arch/ia64/ia64/consinit.c (revision 947fbafb45a25a1ec7d954a49445905bf6263703)
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