Home | History | Annotate | Line # | Download | only in ia64
      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
     70 consinit(void)
     71 {
     72 
     73 	cninit();
     74 }
     75 
     76 static void
     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
    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