11.5Sandvar/*	$NetBSD: consinit.c,v 1.5 2024/02/02 22:33:42 andvar Exp $	*/
21.1Skiyohara/*
31.1Skiyohara * Copyright (c) 2009 KIYOHARA Takashi
41.1Skiyohara * All rights reserved.
51.1Skiyohara *
61.1Skiyohara * Redistribution and use in source and binary forms, with or without
71.1Skiyohara * modification, are permitted provided that the following conditions
81.1Skiyohara * are met:
91.1Skiyohara * 1. Redistributions of source code must retain the above copyright
101.1Skiyohara *    notice, this list of conditions and the following disclaimer.
111.1Skiyohara * 2. Redistributions in binary form must reproduce the above copyright
121.1Skiyohara *    notice, this list of conditions and the following disclaimer in the
131.1Skiyohara *    documentation and/or other materials provided with the distribution.
141.1Skiyohara *
151.1Skiyohara * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
161.1Skiyohara * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
171.1Skiyohara * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
181.1Skiyohara * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
191.1Skiyohara * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
201.1Skiyohara * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
211.1Skiyohara * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
221.1Skiyohara * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
231.1Skiyohara * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
241.1Skiyohara * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
251.1Skiyohara * POSSIBILITY OF SUCH DAMAGE.
261.1Skiyohara */
271.1Skiyohara#include <sys/cdefs.h>
281.5Sandvar__KERNEL_RCSID(0, "$NetBSD: consinit.c,v 1.5 2024/02/02 22:33:42 andvar Exp $");
291.1Skiyohara
301.1Skiyohara#include <sys/param.h>
311.1Skiyohara#include <sys/device.h>
321.1Skiyohara#include <sys/termios.h>
331.1Skiyohara
341.1Skiyohara#include <machine/bus.h>
351.1Skiyohara#include <machine/dig64.h>
361.1Skiyohara#include <machine/md_var.h>
371.1Skiyohara
381.1Skiyohara#include <dev/acpi/acpica.h>
391.1Skiyohara
401.1Skiyohara#include "com.h"
411.1Skiyohara#include "vga.h"
421.1Skiyohara#include "ssccons.h"
431.1Skiyohara
441.1Skiyohara#include <dev/cons.h>
451.1Skiyohara#if NCOM > 0
461.1Skiyohara#include <dev/ic/comvar.h>
471.1Skiyohara#endif
481.1Skiyohara#if NVGA > 0
491.1Skiyohara#include <dev/ic/vgareg.h>
501.1Skiyohara#include <dev/ic/vgavar.h>
511.1Skiyohara#endif
521.1Skiyohara
531.1Skiyohara
541.1Skiyoharastatic void pcdp_cnprobe(struct consdev *);
551.1Skiyoharastatic void pcdp_cninit(struct consdev *);
561.1Skiyohara
571.1Skiyoharacons_decl(ssc);
581.1Skiyohara
591.1Skiyoharastruct consdev constab[] = {
601.1Skiyohara	{ pcdp_cnprobe, pcdp_cninit,
611.1Skiyohara	  NULL, NULL, NULL, NULL, NULL, NULL, NODEV, CN_DEAD },
621.1Skiyohara#if NSSCCONS > 0
631.1Skiyohara	cons_init(ssc),
641.1Skiyohara#endif
651.1Skiyohara	{ NULL }
661.1Skiyohara};
671.1Skiyohara
681.1Skiyohara
691.1Skiyoharavoid
701.2Skiyoharaconsinit(void)
711.1Skiyohara{
721.1Skiyohara
731.1Skiyohara	cninit();
741.1Skiyohara}
751.1Skiyohara
761.1Skiyoharastatic void
771.1Skiyoharapcdp_cnprobe(struct consdev *cn)
781.1Skiyohara{
791.1Skiyohara	struct dig64_hcdp_table *tbl;
801.1Skiyohara	union dev_desc *desc;
811.1Skiyohara	uint64_t hcdp;
821.1Skiyohara	int n, m;
831.1Skiyohara
841.1Skiyohara	hcdp = ia64_get_hcdp();
851.1Skiyohara	if (hcdp != 0) {
861.1Skiyohara		tbl = (void*)IA64_PHYS_TO_RR7(hcdp);
871.1Skiyohara		n = 0;
881.1Skiyohara		m = tbl->length - sizeof(struct dig64_hcdp_table);
891.1Skiyohara		while (n < m) {
901.1Skiyohara			desc = (union dev_desc *)((char *)tbl->entry + n);
911.1Skiyohara#if NVGA > 0
921.1Skiyohara			if (devdesc->type ==
931.1Skiyohara			    (DIG64_ENTRYTYPE_VGA | DIG64_ENTRYTYPE_OUTONLY)) {
941.1Skiyohara#if defined(DIAGNOSTIC)
951.1Skiyohara				if (tbl->revision < 3)
961.1Skiyohara					panic("PCDP found in HCDP rev.%d."
971.5Sandvar					    " Maybe unsupported PCDP",
981.1Skiyohara					    tbl->revision);
991.1Skiyohara#endif
1001.1Skiyohara				cn->cn_pri = CN_NORMAL;
1011.1Skiyohara				break;
1021.1Skiyohara			}
1031.1Skiyohara#endif
1041.1Skiyohara#if NCOM > 0
1051.1Skiyohara			if (desc->type == DIG64_HCDP_CONSOLE) {
1061.1Skiyohara				cn->cn_pri = CN_REMOTE;
1071.1Skiyohara				break;
1081.1Skiyohara			}
1091.1Skiyohara#endif
1101.1Skiyohara
1111.1Skiyohara			if (desc->type == DIG64_ENTRYTYPE_TYPE0 ||
1121.1Skiyohara			    desc->type == DIG64_ENTRYTYPE_TYPE1)
1131.1Skiyohara				n += sizeof(struct dig64_hcdp_entry);
1141.1Skiyohara			else
1151.1Skiyohara				n += desc->pcdp.length;
1161.1Skiyohara		}
1171.1Skiyohara	}
1181.1Skiyohara	if (cn->cn_pri != CN_DEAD)
1191.1Skiyohara		cn->cn_dev = ~NODEV;	/* Shall we makedev()? */
1201.1Skiyohara}
1211.1Skiyohara
1221.1Skiyoharastatic void
1231.1Skiyoharapcdp_cninit(struct consdev *cn)
1241.1Skiyohara{
1251.1Skiyohara	struct dig64_hcdp_table *tbl;
1261.4Smartin#if NVGA > 0 || NCOM > 0
1271.1Skiyohara	union dev_desc *desc;
1281.3Smartin#endif
1291.1Skiyohara	uint64_t hcdp;
1301.1Skiyohara	int n, m;
1311.1Skiyohara
1321.1Skiyohara	hcdp = ia64_get_hcdp();
1331.1Skiyohara	if (hcdp == 0)
1341.1Skiyohara		panic("lost console...\n");
1351.1Skiyohara
1361.1Skiyohara	tbl = (void *)IA64_PHYS_TO_RR7(hcdp);
1371.1Skiyohara	n = 0;
1381.1Skiyohara	m = tbl->length - sizeof(struct dig64_hcdp_table);
1391.1Skiyohara	while (n < m) {
1401.4Smartin#if NVGA > 0 || NCOM > 0
1411.1Skiyohara		desc = (union dev_desc *)((char *)tbl->entry + n);
1421.4Smartin#endif
1431.1Skiyohara
1441.1Skiyohara/* not yet... */
1451.1Skiyohara/* Our VGA is Framebuffer? */
1461.4Smartin#if NVGA > 0
1471.1Skiyohara		if (cn->cn_pri == CN_NORMAL &&
1481.1Skiyohara		    desc->type ==
1491.1Skiyohara			    (DIG64_ENTRYTYPE_VGA | DIG64_ENTRYTYPE_OUTONLY)) {
1501.1Skiyohara			struct dig64_pcdp_entry *ent = &desc->pcdp;
1511.1Skiyohara
1521.1Skiyohara			if (ent->specs.type == DIG64_PCDP_SPEC_PCI) {
1531.1Skiyohara				struct dig64_pci_spec *spec = ent->specs.pci;
1541.1Skiyohara
1551.1Skiyohara				if (spec->flags & DIG64_FLAGS_MMIO_TRA_VALID)
1561.1Skiyohara					(void*)spec->mmio_tra;
1571.1Skiyohara				if (spec->flags & DIG64_FLAGS_IOPORT_TRA_VALID)
1581.1Skiyohara					(void*)spec->ioport_tra;
1591.1Skiyohara			}
1601.1Skiyohara
1611.1Skiyohara			break;
1621.1Skiyohara		}
1631.1Skiyohara#endif
1641.1Skiyohara#if NCOM > 0
1651.1Skiyohara		if (cn->cn_pri == CN_REMOTE &&
1661.1Skiyohara		    desc->type == DIG64_HCDP_CONSOLE) {
1671.1Skiyohara			struct dig64_hcdp_entry *ent = &desc->uart;
1681.1Skiyohara			bus_addr_t ioaddr;
1691.1Skiyohara			bus_space_tag_t iot;
1701.1Skiyohara			const uint64_t rate =
1711.1Skiyohara			    ((uint64_t)ent->baud_high << 32) | ent->baud_low;
1721.1Skiyohara			tcflag_t cflag =
1731.1Skiyohara			    TTYDEF_CFLAG & ~(CSIZE | PARENB | PARODD);
1741.1Skiyohara
1751.1Skiyohara			switch (ent->databits) {
1761.1Skiyohara			case 5:
1771.1Skiyohara				cflag = CS5;
1781.1Skiyohara				break;
1791.1Skiyohara			case 6:
1801.1Skiyohara				cflag = CS6;
1811.1Skiyohara				break;
1821.1Skiyohara			case 7:
1831.1Skiyohara				cflag = CS7;
1841.1Skiyohara				break;
1851.1Skiyohara			case 8:
1861.1Skiyohara				cflag = CS8;
1871.1Skiyohara				break;
1881.1Skiyohara			default:
1891.1Skiyohara				panic("unsupported databits %d\n",
1901.1Skiyohara				    ent->databits);
1911.1Skiyohara			}
1921.1Skiyohara			switch (ent->parity) {
1931.1Skiyohara			case DIG64_HCDP_PARITY_NO:
1941.1Skiyohara				break;
1951.1Skiyohara			case DIG64_HCDP_PARITY_ODD:
1961.1Skiyohara				cflag |= PARODD;
1971.1Skiyohara
1981.1Skiyohara				/* FALLTHROUGH */
1991.1Skiyohara
2001.1Skiyohara			case DIG64_HCDP_PARITY_EVEN:
2011.1Skiyohara				cflag |= PARENB;
2021.1Skiyohara				break;
2031.1Skiyohara			case DIG64_HCDP_PARITY_MARK:
2041.1Skiyohara			case DIG64_HCDP_PARITY_SPACE:
2051.1Skiyohara			default:
2061.1Skiyohara				panic("unsupported parity type %d\n",
2071.1Skiyohara				    ent->parity);
2081.1Skiyohara			}
2091.1Skiyohara			if (ent->stopbits == DIG64_HCDP_STOPBITS_1)
2101.1Skiyohara				cflag &= ~CSTOPB;
2111.1Skiyohara			else if (ent->stopbits == DIG64_HCDP_STOPBITS_2)
2121.1Skiyohara				cflag |= CSTOPB;
2131.1Skiyohara			else
2141.1Skiyohara				panic("unsupported stopbits type %d\n",
2151.1Skiyohara				    ent->stopbits);
2161.1Skiyohara			iot = (ent->address.addr_space ==
2171.1Skiyohara						ACPI_ADR_SPACE_SYSTEM_MEMORY) ?
2181.1Skiyohara			    IA64_BUS_SPACE_MEM : IA64_BUS_SPACE_IO;
2191.1Skiyohara			ioaddr = ((uint64_t)ent->address.addr_high << 32) |
2201.1Skiyohara			    ent->address.addr_low;
2211.1Skiyohara			comcnattach(iot, ioaddr, rate,
2221.1Skiyohara			    (ent->pclock != 0) ? ent->pclock : COM_FREQ,
2231.1Skiyohara			    COM_TYPE_NORMAL, cflag);
2241.1Skiyohara			break;
2251.1Skiyohara		}
2261.1Skiyohara#endif
2271.1Skiyohara	}
2281.1Skiyohara}
229