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