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