xref: /dragonfly/stand/boot/pc32/boot2/sio.S (revision 479ab7f0492f2a51b48e8537e4f1dc686fc6014b)
1/*
2 * Copyright (c) 1998 Robert Nordier
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are freely
6 * permitted provided that the above copyright notice and this
7 * paragraph and the following disclaimer are duplicated in all
8 * such forms.
9 *
10 * This software is provided "AS IS" and without any express or
11 * implied warranties, including, without limitation, the implied
12 * warranties of merchantability and fitness for a particular
13 * purpose.
14 *
15 * $FreeBSD: src/sys/boot/i386/boot2/sio.s,v 1.4 1999/08/28 00:40:02 peter Exp $
16 * $DragonFly: src/sys/boot/pc32/boot2/sio.S,v 1.8 2006/08/12 05:42:26 swildner Exp $
17 */
18                    .set SIO_PRT,SIOPRT           # Base port
19                    .set SIO_FMT,SIOFMT           # 8N1
20                    .set SIO_DIV,(115200/SIOSPD)  # 115200 / SPD
21
22                    .globl sio_init
23                    .globl sio_flush
24                    .globl sio_putc
25                    .globl sio_getc
26                    .globl sio_ischar
27
28                    /*
29                     * int sio_init(void)
30                     *
31                     * returns non-zero if we couldn't init, which can happen if
32                     * the serial port is unmapped and the inb's all return
33                     * 0xFF (we fail to flush the input).
34                     */
35sio_init: movw $SIO_PRT+0x3,%dx                   # Data format reg
36                    movb $SIO_FMT|0x80,%al                  # Set format and DLAB
37                    outb %al,(%dx)                          # BASE+3
38                    subb $0x3,%dl
39                    movw $SIO_DIV,%ax             # divisor
40                    outw %ax,(%dx)                          # BASE+0 (divisor w/ DLAB set)
41                    movw $SIO_PRT+0x2,%dx
42                    movb $0x01,%al                          # Enable FIFO
43
44                    /*
45                     * DISABLED - apparently many new laptops only implement
46                     * 8250s, this might crash them? XXX
47                     */
48                     /* outb %al,(%dx) */                             # BASE+2
49                    incl %edx
50                    movb $SIO_FMT,%al             # Clear DLAB
51                    outb %al,(%dx)                          # BASE+3
52                    incl %edx
53                    movb $0x3,%al                           # RTS+DTR
54                    outb %al,(%dx)                          # BASE+4
55                    incl %edx                     # BASE+5 Line status reg
56
57                    /*
58                     * fall through to io_flush
59                     *
60                     * sio_flush: flush pending data in the serial port,
61                     * return non-zero if we were unable to flush (aka
62                     * ischar always returned true)
63                     */
64sio_flush:          movb $1,%ch                             # let %cl be garbage
651:                  call sio_getc.1
66                    call sio_ischar
67                    loopnz 1b
68                    ret
69
70                    /*
71                     * void sio_putc(int c)
72                     */
73sio_putc: movw $SIO_PRT+0x5,%dx                   # Line status reg
74                    movb $0x40,%ch                          # Timeout counter.  Allow %cl
75                                                            # to contain garbage.
76sio_putc.1:         inb (%dx),%al                           # Transmitter buffer empty?
77                    testb $0x20,%al
78                    loopz sio_putc.1              # No
79                    jz sio_putc.2                           # If timeout
80                    movb 0x4(%esp,1),%al                    # Get character
81                    subb $0x5,%dl                           # Transmitter hold reg
82                    outb %al,(%dx)                          # Write character
83sio_putc.2:         ret
84
85                    /*
86                     * int sio_getc(void)
87                     */
88sio_getc: call sio_ischar               # Character available?
89                    jz sio_getc                             # No
90sio_getc.1:         subb $0x5,%dl                           # Receiver buffer reg
91                    inb (%dx),%al                           # Read character
92                    ret
93
94                    /*
95                     * int sio_ischar(void)
96                     */
97sio_ischar:         movw $SIO_PRT+0x5,%dx                   # Line status register
98                    xorl %eax,%eax                          # Zero
99                    inb (%dx),%al                           # Received data ready?
100                    andb $0x1,%al
101                    ret
102
103                    .globl inbser
104inbser:             movw $SIO_PRT+5,%dx
105                    inb (%dx),%al
106                    ret
107