1/* $NetBSD$ */ 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$"); 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 54static void pcdp_cnprobe(struct consdev *); 55static void pcdp_cninit(struct consdev *); 56 57cons_decl(ssc); 58 59struct 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 69void 70consinit() 71{ 72 73 cninit(); 74} 75 76static void 77pcdp_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 unsupport 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 122static void 123pcdp_cninit(struct consdev *cn) 124{ 125 struct dig64_hcdp_table *tbl; 126 union dev_desc *desc; 127 uint64_t hcdp; 128 int n, m; 129 130 hcdp = ia64_get_hcdp(); 131 if (hcdp == 0) 132 panic("lost console...\n"); 133 134 tbl = (void *)IA64_PHYS_TO_RR7(hcdp); 135 n = 0; 136 m = tbl->length - sizeof(struct dig64_hcdp_table); 137 while (n < m) { 138 desc = (union dev_desc *)((char *)tbl->entry + n); 139#if NVGA > 0 140 141/* not yet... */ 142/* Our VGA is Framebuffer? */ 143 144 if (cn->cn_pri == CN_NORMAL && 145 desc->type == 146 (DIG64_ENTRYTYPE_VGA | DIG64_ENTRYTYPE_OUTONLY)) { 147 struct dig64_pcdp_entry *ent = &desc->pcdp; 148 149 if (ent->specs.type == DIG64_PCDP_SPEC_PCI) { 150 struct dig64_pci_spec *spec = ent->specs.pci; 151 152 if (spec->flags & DIG64_FLAGS_MMIO_TRA_VALID) 153 (void*)spec->mmio_tra; 154 if (spec->flags & DIG64_FLAGS_IOPORT_TRA_VALID) 155 (void*)spec->ioport_tra; 156 } 157 158 break; 159 } 160#endif 161#if NCOM > 0 162 if (cn->cn_pri == CN_REMOTE && 163 desc->type == DIG64_HCDP_CONSOLE) { 164 struct dig64_hcdp_entry *ent = &desc->uart; 165 bus_addr_t ioaddr; 166 bus_space_tag_t iot; 167 const uint64_t rate = 168 ((uint64_t)ent->baud_high << 32) | ent->baud_low; 169 tcflag_t cflag = 170 TTYDEF_CFLAG & ~(CSIZE | PARENB | PARODD); 171 172 switch (ent->databits) { 173 case 5: 174 cflag = CS5; 175 break; 176 case 6: 177 cflag = CS6; 178 break; 179 case 7: 180 cflag = CS7; 181 break; 182 case 8: 183 cflag = CS8; 184 break; 185 default: 186 panic("unsupported databits %d\n", 187 ent->databits); 188 } 189 switch (ent->parity) { 190 case DIG64_HCDP_PARITY_NO: 191 break; 192 case DIG64_HCDP_PARITY_ODD: 193 cflag |= PARODD; 194 195 /* FALLTHROUGH */ 196 197 case DIG64_HCDP_PARITY_EVEN: 198 cflag |= PARENB; 199 break; 200 case DIG64_HCDP_PARITY_MARK: 201 case DIG64_HCDP_PARITY_SPACE: 202 default: 203 panic("unsupported parity type %d\n", 204 ent->parity); 205 } 206 if (ent->stopbits == DIG64_HCDP_STOPBITS_1) 207 cflag &= ~CSTOPB; 208 else if (ent->stopbits == DIG64_HCDP_STOPBITS_2) 209 cflag |= CSTOPB; 210 else 211 panic("unsupported stopbits type %d\n", 212 ent->stopbits); 213 iot = (ent->address.addr_space == 214 ACPI_ADR_SPACE_SYSTEM_MEMORY) ? 215 IA64_BUS_SPACE_MEM : IA64_BUS_SPACE_IO; 216 ioaddr = ((uint64_t)ent->address.addr_high << 32) | 217 ent->address.addr_low; 218 comcnattach(iot, ioaddr, rate, 219 (ent->pclock != 0) ? ent->pclock : COM_FREQ, 220 COM_TYPE_NORMAL, cflag); 221 break; 222 } 223#endif 224 } 225} 226