]>
git.saurik.com Git - apple/xnu.git/blob - pexpert/i386/pe_serial.c
2bce2811c896823c1146c0896b1c898df545bcbb
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
25 * Polled-mode 16x50 UART driver.
28 #include <pexpert/protos.h>
29 #include <pexpert/pexpert.h>
31 void serial_putc(char);
32 int serial_getc(void);
33 int serial_init(void);
35 /* standard port addresses */
37 COM1_PORT_ADDR
= 0x3f8,
38 COM2_PORT_ADDR
= 0x2f8
41 /* UART register offsets */
43 UART_RBR
= 0, /* receive buffer Register (R) */
44 UART_THR
= 0, /* transmit holding register (W) */
45 UART_DLL
= 0, /* DLAB = 1, divisor latch (LSB) */
46 UART_IER
= 1, /* interrupt enable register */
47 UART_DLM
= 1, /* DLAB = 1, divisor latch (MSB) */
48 UART_IIR
= 2, /* interrupt ident register (R) */
49 UART_FCR
= 2, /* fifo control register (W) */
50 UART_LCR
= 3, /* line control register */
51 UART_MCR
= 4, /* modem control register */
52 UART_LSR
= 5, /* line status register */
53 UART_MSR
= 6 /* modem status register */
57 UART_LCR_8BITS
= 0x03,
77 static unsigned uart_baud_rate
= 115200;
78 #define UART_PORT_ADDR COM1_PORT_ADDR
80 #define UART_CLOCK 1843200 /* 1.8432 MHz clock */
82 #define WRITE(r, v) outb(UART_PORT_ADDR + UART_##r, v)
83 #define READ(r) inb(UART_PORT_ADDR + UART_##r)
84 #define DELAY(x) { volatile int _d_; for (_d_ = 0; _d_ < (10000*x); _d_++) ; }
86 static int uart_initted
= 0; /* 1 if init'ed */
91 /* Verify that the Divisor Register is accessible */
93 WRITE( LCR
, UART_LCR_DLAB
);
95 if (READ(DLL
) != 0x5a) return 0;
97 if (READ(DLL
) != 0xa5) return 0;
103 uart_set_baud_rate( unsigned long baud_rate
)
105 const unsigned char lcr
= READ( LCR
);
108 if (baud_rate
== 0) baud_rate
= 9600;
109 div
= UART_CLOCK
/ 16 / baud_rate
;
110 WRITE( LCR
, lcr
| UART_LCR_DLAB
);
111 WRITE( DLM
, (unsigned char)(div
>> 8) );
112 WRITE( DLL
, (unsigned char) div
);
113 WRITE( LCR
, lcr
& ~UART_LCR_DLAB
);
119 if (!uart_initted
) return;
121 /* Wait for THR empty */
122 while ( !(READ(LSR
) & UART_LSR_THRE
) ) DELAY(1);
131 * This function returns:
133 * -2 : receiver error
134 * >0 : character received
139 if (!uart_initted
) return -1;
143 if ( lsr
& (UART_LSR_FE
| UART_LSR_PE
| UART_LSR_OE
) )
145 READ( RBR
); /* discard */
149 if ( lsr
& UART_LSR_DR
)
157 int serial_init( void )
159 unsigned serial_baud_rate
= 0;
161 if ( /*uart_initted ||*/ uart_probe() == 0 ) return 0;
163 /* Disable hardware interrupts */
168 /* Disable FIFO's for 16550 devices */
172 /* Set for 8-bit, no parity, DLAB bit cleared */
174 WRITE( LCR
, UART_LCR_8BITS
);
176 /* Set baud rate - use the supplied boot-arg if available */
178 if (PE_parse_boot_arg("serialbaud", &serial_baud_rate
))
181 if (!((UART_CLOCK
/ 16) % serial_baud_rate
)) {
182 uart_baud_rate
= serial_baud_rate
;
185 uart_set_baud_rate( uart_baud_rate
);
187 /* Assert DTR# and RTS# lines (OUT2?) */
189 WRITE( MCR
, UART_MCR_DTR
| UART_MCR_RTS
);
191 /* Clear any garbage in the input buffer */
200 void serial_putc( char c
)
203 if (c
== '\n') uart_putc('\r');
206 int serial_getc( void )