1 /*
2  *  linux/drivers/char/hcdp_serial.c
3  *
4  *  Copyright (C) 2002  Hewlett-Packard Co.
5  *  Copyright (C) 2002  Khalid Aziz <khalid_aziz@hp.com>
6  *
7  *  Parse the EFI HCDP table to locate serial console and debug ports
8  *  and initialize them
9  *
10  */
11 #include <linux/kernel.h>
12 #include <linux/types.h>
13 #include <linux/pci.h>
14 #include <linux/pm.h>
15 #include <linux/init.h>
16 #include <linux/serial.h>
17 #include <linux/serialP.h>
18 #include <linux/efi.h>
19 #include <asm/serial.h>
20 #include <asm/io.h>
21 #include <linux/hcdp_serial.h>
22 
23 #undef SERIAL_DEBUG_HCDP
24 
25 extern struct serial_state rs_table[];
26 extern int serial_nr_ports;
27 
28 /*
29  * Parse the HCDP table to find descriptions for headless console and
30  * debug serial ports and add them to rs_table[]. A pointer to HCDP
31  * table is passed as parameter. This function should be called
32  * before serial_console_init() is called to make sure the HCDP serial
33  * console will be available for use. IA-64 kernel calls this function
34  * from setup_arch() after the EFI and ACPI tables have been parsed.
35  */
setup_serial_hcdp(void * tablep)36 void __init setup_serial_hcdp(void *tablep)
37 {
38 	hcdp_t hcdp;
39 	hcdp_dev_t *hcdp_dev;
40 	struct serial_struct serial_req;
41 	unsigned long iobase;
42 	int global_sys_irq;
43 	int i, nr;
44 	int shift_once = 1;
45 
46 #ifdef SERIAL_DEBUG_HCDP
47 	printk("Entering setup_serial_hcdp()\n");
48 #endif
49 
50 	/* Verify we have a valid table pointer */
51 	if (tablep == NULL) {
52 		return;
53 	}
54 
55 	/*
56 	 * We do not trust firmware to give us a table starting at an
57 	 * aligned address. Make a local copy of the HCDP table with
58 	 * aligned structures.
59 	 */
60 	memcpy(&hcdp, tablep, sizeof(hcdp));
61 
62 	/*
63 	 * Perform a sanity check on the table. Table should have a
64 	 * signature of "HCDP" and it should be atleast 82 bytes
65 	 * long to have any useful information.
66 	 */
67 	if ((strncmp(hcdp.signature, HCDP_SIGNATURE,
68 					HCDP_SIG_LEN) != 0)) {
69 		return;
70 	}
71 	if (hcdp.len < 82) {
72 		return;
73 	}
74 
75 #ifdef SERIAL_DEBUG_HCDP
76 	printk("setup_serial_hcdp(): table pointer = 0x%p\n", tablep);
77 	printk("                     sig = '%c%c%c%c'\n",
78 			hcdp.signature[0],
79 			hcdp.signature[1],
80 			hcdp.signature[2],
81 			hcdp.signature[3]);
82 	printk("                     length = %d\n", hcdp.len);
83 	printk("                     Rev = %d\n", hcdp.rev);
84 	printk("                     OEM ID = %c%c%c%c%c%c\n",
85 			hcdp.oemid[0], hcdp.oemid[1], hcdp.oemid[2],
86 			hcdp.oemid[3], hcdp.oemid[4], hcdp.oemid[5]);
87 	printk("                     Number of entries = %d\n", hcdp.num_entries);
88 #endif
89 
90 	/*
91 	 * Parse each device entry
92 	 */
93 	for (nr=0; nr<hcdp.num_entries; nr++) {
94 		hcdp_dev = &(hcdp.hcdp_dev[nr]);
95 
96 		/*
97 		 * We will parse only the primary console device
98 		 * which is the first entry for these devices. We will
99 		 * ignore rest of the entries for the same type device that
100 		 * has already been parsed and initialized
101 		 */
102 		if (hcdp_dev->type != HCDP_DEV_CONSOLE)
103 			continue;
104 
105 		iobase = (u64)(hcdp_dev->base_addr.addrhi)<<32 | hcdp_dev->base_addr.addrlo;
106 		global_sys_irq = hcdp_dev->global_int;
107 #ifdef SERIAL_DEBUG_HCDP
108 		printk("                 type = %s\n",
109 			((hcdp_dev->type == HCDP_DEV_CONSOLE)?"Headless Console":((hcdp_dev->type == HCDP_DEV_DEBUG)?"Debug port":"Huh????")));
110 		printk("                 Base address space = %s\n", ((hcdp_dev->base_addr.space_id == ACPI_MEM_SPACE)?"Memory Space":((hcdp_dev->base_addr.space_id == ACPI_IO_SPACE)?"I/O space":"PCI space")));
111 		printk("                 Base address = 0x%p\n", iobase);
112 		printk("                 Global System Int = %d\n", global_sys_irq);
113 		printk("                 Baud rate = %d\n", hcdp_dev->baud);
114 		printk("                 Bits = %d\n", hcdp_dev->bits);
115 		printk("                 Clock rate = %d\n", hcdp_dev->clock_rate);
116 		if (hcdp_dev->base_addr.space_id == ACPI_PCICONF_SPACE) {
117 			printk("                     PCI serial port:\n");
118 			printk("                         Bus %d, Device %d, Vendor ID 0x%x, Dev ID 0x%x\n",
119 			hcdp_dev->pci_bus, hcdp_dev->pci_dev,
120 			hcdp_dev->pci_vendor_id, hcdp_dev->pci_dev_id);
121 		}
122 #endif
123 
124 
125 		/*
126 	 	* Now build a serial_req structure to update the entry in
127 	 	* rs_table for the headless console port.
128 	 	*/
129 		if (hcdp_dev->clock_rate)
130 			serial_req.baud_base = hcdp_dev->clock_rate;
131 		else
132 			serial_req.baud_base = DEFAULT_BAUD_BASE;
133 		/*
134 	 	* Check if this is an I/O mapped address or a memory mapped address
135 	 	*/
136 		if (hcdp_dev->base_addr.space_id == ACPI_MEM_SPACE) {
137 			serial_req.port = 0;
138 			serial_req.port_high = 0;
139 			serial_req.iomem_base = (void *)ioremap(iobase, 64);
140 			serial_req.io_type = SERIAL_IO_MEM;
141 		}
142 		else if (hcdp_dev->base_addr.space_id == ACPI_IO_SPACE) {
143 			serial_req.port = (unsigned long) iobase & 0xffffffff;
144 			serial_req.port_high = (unsigned long)(((u64)iobase) >> 32);
145 			serial_req.iomem_base = NULL;
146 			serial_req.io_type = SERIAL_IO_PORT;
147 		}
148 		else if (hcdp_dev->base_addr.space_id == ACPI_PCICONF_SPACE) {
149 			printk("WARNING: No support for PCI serial console\n");
150 			return;
151 		}
152 
153 		/*
154 		 * Check if HCDP defines a port already in rs_table
155 		 */
156 		for (i = 0; i < serial_nr_ports; i++) {
157 			if ((rs_table[i].port == serial_req.port) &&
158 				(rs_table[i].iomem_base==serial_req.iomem_base))
159 				break;
160 		}
161 		if (i == serial_nr_ports) {
162 			/*
163 			 * We have reserved a slot for HCDP defined console
164 			 * port at HCDP_SERIAL_CONSOLE_PORT in rs_table
165 			 * which is not 0. This means using this slot would
166 			 * put the console at a device other than ttyS0.
167 			 * Users expect to see the console at ttyS0. Now
168 			 * that we have determined HCDP does describe a
169 			 * serial console and it is not one of the compiled
170 			 * in ports, let us move the entries in rs_table
171 			 * up by a slot towards HCDP_SERIAL_CONSOLE_PORT to
172 			 * make room for the HCDP console at ttyS0. We may go
173 			 * through this loop more than once if
174 			 * early_serial_setup() fails. Make sure we shift the
175 			 * entries in rs_table only once.
176 			 */
177 			if (shift_once) {
178 				int j;
179 
180 				for (j=HCDP_SERIAL_CONSOLE_PORT; j>0; j--)
181 					memcpy(rs_table+j, rs_table+j-1,
182 						sizeof(struct serial_state));
183 				shift_once = 0;
184 			}
185 			serial_req.line = 0;
186 		}
187 		else
188 			serial_req.line = i;
189 
190 		/*
191 	 	* If the table does not have IRQ information, use 0 for IRQ.
192 	 	* This will force rs_init() to probe for IRQ.
193 	 	*/
194 		serial_req.irq = global_sys_irq;
195 		if (global_sys_irq == 0) {
196 			serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF;
197 		}
198 		else {
199 			serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF|
200 						ASYNC_AUTO_IRQ;
201 		}
202 
203 		serial_req.xmit_fifo_size = serial_req.custom_divisor = 0;
204 		serial_req.close_delay = serial_req.hub6 = serial_req.closing_wait = 0;
205 		serial_req.iomem_reg_shift = 0;
206 		if (early_serial_setup(&serial_req) < 0) {
207 			printk("setup_serial_hcdp(): early_serial_setup() for HCDP serial console port failed. Will try any additional consoles in HCDP.\n");
208 			continue;
209 		}
210 		else
211 			if (hcdp_dev->type == HCDP_DEV_CONSOLE)
212 				break;
213 #ifdef SERIAL_DEBUG_HCDP
214 		printk("\n");
215 #endif
216 	}
217 
218 #ifdef SERIAL_DEBUG_HCDP
219 	printk("Leaving setup_serial_hcdp()\n");
220 #endif
221 }
222 
223 #ifdef CONFIG_IA64_EARLY_PRINTK_UART
hcdp_early_uart(void)224 unsigned long hcdp_early_uart(void)
225 {
226 	efi_system_table_t *systab;
227 	efi_config_table_t *config_tables;
228 	hcdp_t *hcdp = 0;
229 	hcdp_dev_t *dev;
230 	int i;
231 
232 	systab = (efi_system_table_t *) ia64_boot_param->efi_systab;
233 	if (!systab)
234 		return 0;
235 	systab = __va(systab);
236 
237 	config_tables = (efi_config_table_t *) systab->tables;
238 	if (!config_tables)
239 		return 0;
240 	config_tables = __va(config_tables);
241 
242 	for (i = 0; i < systab->nr_tables; i++) {
243 		if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {
244 			hcdp = (hcdp_t *) config_tables[i].table;
245 			break;
246 		}
247 	}
248 	if (!hcdp)
249 		return 0;
250 	hcdp = __va(hcdp);
251 
252 	for (i = 0, dev = hcdp->hcdp_dev; i < hcdp->num_entries; i++, dev++) {
253 		if (dev->type == HCDP_DEV_CONSOLE)
254 			return (u64) dev->base_addr.addrhi << 32
255 				| dev->base_addr.addrlo;
256 	}
257 	return 0;
258 }
259 #endif
260