diff --git a/sys/boot/i386/btx/btx/Makefile b/sys/boot/i386/btx/btx/Makefile index d3ead1b889fe..1d03cfdf5bd8 100644 --- a/sys/boot/i386/btx/btx/Makefile +++ b/sys/boot/i386/btx/btx/Makefile @@ -14,6 +14,15 @@ BOOT_BTX_FLAGS=0x0 AFLAGS+= --defsym BTX_FLAGS=${BOOT_BTX_FLAGS} +.if defined(BTX_SERIAL) +BOOT_COMCONSOLE_PORT?= 0x3f8 +BOOT_COMCONSOLE_SPEED?= 9600 +B2SIOFMT?= 0x3 + +M4FLAGS+= -DBTX_SERIAL -DSIOPRT=${BOOT_COMCONSOLE_PORT} \ + -DSIOFMT=${B2SIOFMT} -DSIOSPD=${BOOT_COMCONSOLE_SPEED} +.endif + ORG= 0x9000 all: btx diff --git a/sys/boot/i386/btx/btx/btx.S b/sys/boot/i386/btx/btx/btx.S index b04299bce1ee..afa20fd51934 100644 --- a/sys/boot/i386/btx/btx/btx.S +++ b/sys/boot/i386/btx/btx/btx.S @@ -240,6 +240,9 @@ init.8: xorl %ecx,%ecx # Zero movb $0x7,%cl # Set remaining init.9: push $0x0 # general loop init.9 # registers +ifdef(`BTX_SERIAL',` + call sio_init # setup the serial console +') popa # and initialize popl %es # Initialize popl %ds # user @@ -967,6 +970,80 @@ putstr: lodsb # Load char testb %al,%al # End of string? jnz putstr.0 # No ret # To caller +ifdef(`BTX_SERIAL',` + .set SIO_PRT,SIOPRT # Base port + .set SIO_FMT,SIOFMT # 8N1 + .set SIO_DIV,(115200/SIOSPD) # 115200 / SPD + +# void sio_init(void) + +sio_init: movw $SIO_PRT+0x3,%dx # Data format reg + movb $SIO_FMT|0x80,%al # Set format + outb %al,(%dx) # and DLAB + pushl %edx # Save + subb $0x3,%dl # Divisor latch reg + movw $SIO_DIV,%ax # Set + outw %ax,(%dx) # BPS + popl %edx # Restore + movb $SIO_FMT,%al # Clear + outb %al,(%dx) # DLAB + incl %edx # Modem control reg + movb $0x3,%al # Set RTS, + outb %al,(%dx) # DTR + incl %edx # Line status reg + +# void sio_flush(void) + +sio_flush.0: call sio_getc.1 # Get character +sio_flush: call sio_ischar # Check for character + jnz sio_flush.0 # Till none + ret # To caller + +# void sio_putc(int c) + +sio_putc: movw $SIO_PRT+0x5,%dx # Line status reg + xor %ecx,%ecx # Timeout + movb $0x40,%ch # counter +sio_putc.1: inb (%dx),%al # Transmitter + testb $0x20,%al # buffer empty? + loopz sio_putc.1 # No + jz sio_putc.2 # If timeout + movb 0x4(%esp,1),%al # Get character + subb $0x5,%dl # Transmitter hold reg + outb %al,(%dx) # Write character +sio_putc.2: ret $0x4 # To caller + +# int sio_getc(void) + +sio_getc: call sio_ischar # Character available? + jz sio_getc # No +sio_getc.1: subb $0x5,%dl # Receiver buffer reg + inb (%dx),%al # Read character + ret # To caller + +# int sio_ischar(void) + +sio_ischar: movw $SIO_PRT+0x5,%dx # Line status register + xorl %eax,%eax # Zero + inb (%dx),%al # Received data + andb $0x1,%al # ready? + ret # To caller + +# +# Output character AL to the serial console. +# +putchr: pusha # Save + cmpb $10, %al # is it a newline? + jne putchr.1 # no?, then leave + push $13 # output a carriage + call sio_putc # return first + movb $10, %al # restore %al +putchr.1: pushl %eax # Push the character + # onto the stack + call sio_putc # Output the character + popa # Restore + ret # To caller +',` # # Output character AL to the console. # diff --git a/sys/boot/i386/btx/btx/btx.s b/sys/boot/i386/btx/btx/btx.s index b04299bce1ee..afa20fd51934 100644 --- a/sys/boot/i386/btx/btx/btx.s +++ b/sys/boot/i386/btx/btx/btx.s @@ -240,6 +240,9 @@ init.8: xorl %ecx,%ecx # Zero movb $0x7,%cl # Set remaining init.9: push $0x0 # general loop init.9 # registers +ifdef(`BTX_SERIAL',` + call sio_init # setup the serial console +') popa # and initialize popl %es # Initialize popl %ds # user @@ -967,6 +970,80 @@ putstr: lodsb # Load char testb %al,%al # End of string? jnz putstr.0 # No ret # To caller +ifdef(`BTX_SERIAL',` + .set SIO_PRT,SIOPRT # Base port + .set SIO_FMT,SIOFMT # 8N1 + .set SIO_DIV,(115200/SIOSPD) # 115200 / SPD + +# void sio_init(void) + +sio_init: movw $SIO_PRT+0x3,%dx # Data format reg + movb $SIO_FMT|0x80,%al # Set format + outb %al,(%dx) # and DLAB + pushl %edx # Save + subb $0x3,%dl # Divisor latch reg + movw $SIO_DIV,%ax # Set + outw %ax,(%dx) # BPS + popl %edx # Restore + movb $SIO_FMT,%al # Clear + outb %al,(%dx) # DLAB + incl %edx # Modem control reg + movb $0x3,%al # Set RTS, + outb %al,(%dx) # DTR + incl %edx # Line status reg + +# void sio_flush(void) + +sio_flush.0: call sio_getc.1 # Get character +sio_flush: call sio_ischar # Check for character + jnz sio_flush.0 # Till none + ret # To caller + +# void sio_putc(int c) + +sio_putc: movw $SIO_PRT+0x5,%dx # Line status reg + xor %ecx,%ecx # Timeout + movb $0x40,%ch # counter +sio_putc.1: inb (%dx),%al # Transmitter + testb $0x20,%al # buffer empty? + loopz sio_putc.1 # No + jz sio_putc.2 # If timeout + movb 0x4(%esp,1),%al # Get character + subb $0x5,%dl # Transmitter hold reg + outb %al,(%dx) # Write character +sio_putc.2: ret $0x4 # To caller + +# int sio_getc(void) + +sio_getc: call sio_ischar # Character available? + jz sio_getc # No +sio_getc.1: subb $0x5,%dl # Receiver buffer reg + inb (%dx),%al # Read character + ret # To caller + +# int sio_ischar(void) + +sio_ischar: movw $SIO_PRT+0x5,%dx # Line status register + xorl %eax,%eax # Zero + inb (%dx),%al # Received data + andb $0x1,%al # ready? + ret # To caller + +# +# Output character AL to the serial console. +# +putchr: pusha # Save + cmpb $10, %al # is it a newline? + jne putchr.1 # no?, then leave + push $13 # output a carriage + call sio_putc # return first + movb $10, %al # restore %al +putchr.1: pushl %eax # Push the character + # onto the stack + call sio_putc # Output the character + popa # Restore + ret # To caller +',` # # Output character AL to the console. #