Home | History | Annotate | Line # | Download | only in lib
bios_disk.S revision 1.20.6.1
      1 /*	$NetBSD: bios_disk.S,v 1.20.6.1 2011/06/23 14:19:16 cherry Exp $	*/
      2 
      3 /*
      4  * Ported to boot 386BSD by Julian Elischer (julian (at) tfs.com) Sept 1992
      5  *
      6  * Mach Operating System
      7  * Copyright (c) 1992, 1991 Carnegie Mellon University
      8  * All Rights Reserved.
      9  *
     10  * Permission to use, copy, modify and distribute this software and its
     11  * documentation is hereby granted, provided that both the copyright
     12  * notice and this permission notice appear in all copies of the
     13  * software, derivative works or modified versions, and any portions
     14  * thereof, and that both notices appear in supporting documentation.
     15  *
     16  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     17  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
     18  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     19  *
     20  * Carnegie Mellon requests users of this software to return to
     21  *
     22  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     23  *  School of Computer Science
     24  *  Carnegie Mellon University
     25  *  Pittsburgh PA 15213-3890
     26  *
     27  * any improvements or extensions that they make and grant Carnegie Mellon
     28  * the rights to redistribute these changes.
     29  */
     30 
     31 /*
     32   Copyright 1988, 1989, 1990, 1991, 1992
     33    by Intel Corporation, Santa Clara, California.
     34 
     35                 All Rights Reserved
     36 
     37 Permission to use, copy, modify, and distribute this software and
     38 its documentation for any purpose and without fee is hereby
     39 granted, provided that the above copyright notice appears in all
     40 copies and that both the copyright notice and this permission notice
     41 appear in supporting documentation, and that the name of Intel
     42 not be used in advertising or publicity pertaining to distribution
     43 of the software without specific, written prior permission.
     44 
     45 INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
     46 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
     47 IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
     48 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
     49 LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
     50 NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
     51 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     52 */
     53 
     54 /* extracted from netbsd:sys/arch/i386/boot/bios.S */
     55 
     56 #include <machine/asm.h>
     57 
     58 /*
     59  * BIOS call "INT 0x13 Function 0x0" to reset the disk subsystem
     60  *	Call with	%ah = 0x0
     61  *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
     62  *	Return:
     63  *			%al = 0x0 on success; err code on failure
     64  */
     65 ENTRY(biosdisk_reset)
     66 	pusha
     67 
     68 	movb	%al, %dl	# device
     69 
     70 	call	_C_LABEL(prot_to_real)	# enter real mode
     71 	.code16
     72 
     73 	movb	$0x0, %ah	# subfunction
     74 	int	$0x13
     75 	setc	%bl
     76 	movb	%ah, %bh	# save error code
     77 
     78 	calll	_C_LABEL(real_to_prot) # back to protected mode
     79 	.code32
     80 
     81 	movzwl	%bx, %eax	# return value in %eax
     82 	movl	%eax, 28(%esp)
     83 
     84 	popa
     85 	ret
     86 
     87 /*
     88  * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
     89  *	Call with	%ah = 0x2
     90  *			%al = number of sectors
     91  *			%ch = cylinder
     92  *			%cl = sector
     93  *			%dh = head
     94  *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
     95  *			%es:%bx = segment:offset of buffer
     96  *	Return:
     97  *			%al = 0x0 on success; err code on failure
     98  *
     99  * biosdisk_read(dev, cyl, head, sect, count, buff_addr);
    100  *
    101  *  Note: On failure, you must reset the disk with biosdisk_reset() before
    102  *        sending another command.
    103  */
    104 ENTRY(biosdisk_read)
    105 	pusha
    106 
    107 	movb	44(%esp), %dh
    108 	movw	40(%esp), %cx
    109 	xchgb	%ch, %cl	# cylinder; the highest 2 bits of cyl is in %cl
    110 	rorb	$2, %cl
    111 	movb	48(%esp), %al
    112 	orb	%al, %cl
    113 	incb	%cl		# sector; sec starts from 1, not 0
    114 	movb	36(%esp), %dl	# device
    115 	movl	56(%esp), %ebx	# buffer address (may be >64k)
    116 	movb	52(%esp), %al	# number of sectors
    117 
    118 	call	_C_LABEL(prot_to_real)	# enter real mode
    119 	.code16
    120 
    121 	push	%bx
    122 	shrl	$4, %ebx	# max segment
    123 	mov	%ds, %si
    124 	add	%si, %bx
    125 	mov	%bx, %es	# %es:%bx now valid buffer address
    126 	pop	%bx
    127 	and	$0xf, %bx	# and min offset - to avoid overrun
    128 
    129 	movb	$0x2, %ah	# subfunction
    130 	int	$0x13
    131 	setc	%al		# error code is in %ah
    132 
    133 	calll	_C_LABEL(real_to_prot) # back to protected mode
    134 	.code32
    135 
    136 	movl	%eax, 28(%esp)
    137 
    138 	popa
    139 	ret
    140 
    141 /*
    142  * biosdisk_getinfo(int dev):  return a word that represents the
    143  *	max number of sectors, heads and cylinders for this device
    144  */
    145 ENTRY(biosdisk_getinfo)
    146 	push	%es
    147 	pusha
    148 
    149 	movb	%al, %dl		# diskinfo(drive #)
    150 
    151 	call	_C_LABEL(prot_to_real)	# enter real mode
    152 	.code16
    153 
    154 	push	%dx			# save drive #
    155 	movb	$0x08, %ah		# ask for disk info
    156 	int	$0x13
    157 	pop	%bx			# restore drive #
    158 	jnc	ok
    159 
    160 	testb	$0x80, %bl		# is it a hard disk?
    161 	jnz	ok
    162 
    163 	/*
    164 	 * Urk.  Call failed.  It is not supported for floppies by old BIOS's.
    165 	 * Guess it's a 15-sector floppy.  Initialize all the registers for
    166 	 * documentation, although we only need head and sector counts.
    167 	 */
    168 	xorw	%ax, %ax		# set status to success
    169 #	movb	%ah, %bh		# %bh = 0
    170 #	movb	$2, %bl			# %bl bits 0-3 = drive type, 2 = 1.2M
    171 	movb	$79, %ch		# max track
    172 	movb	$15, %cl		# max sector
    173 	movb	$1, %dh			# max head
    174 #	movb	$1, %dl			# # floppy drives installed
    175 	# es:di = parameter table
    176 	# carry = 0
    177 
    178 ok:
    179 	calll	_C_LABEL(real_to_prot)	# back to protected mode
    180 	.code32
    181 
    182 	/* form a longword representing all this gunk */
    183 	shrl	$8, %eax		# clear unnecessary bits
    184 	shll	$24, %eax
    185 	shll	$16, %ecx		# do the same for %ecx
    186 	shrl	$8, %ecx
    187 	movb	%dh, %cl		# max head
    188 	orl	%ecx, %eax		# return value in %eax
    189 	movl	%eax, 28(%esp)
    190 
    191 	popa
    192 	pop	%es
    193 	ret
    194 
    195 /*
    196  * int biosdisk_int13ext(int dev):
    197  *	check for availibility of int13 extensions.
    198  */
    199 ENTRY(biosdisk_int13ext)
    200 	pusha
    201 
    202 	movb	%al, %dl		# drive #
    203 	movw	$0x55aa, %bx
    204 
    205 	call	_C_LABEL(prot_to_real)	# enter real mode
    206 	.code16
    207 
    208 	movb	$0x41, %ah		# ask for disk info
    209 	int	$0x13
    210 	setnc	%dl
    211 
    212 	calll	_C_LABEL(real_to_prot)	# switch back
    213 	.code32
    214 
    215 	movzbl	%dl, %eax		# return value in %eax
    216 
    217 	cmpw	$0xaa55, %bx
    218 	sete	%dl
    219 	andb	%dl, %al
    220 
    221 	andb	%cl, %al
    222 	movl	%eax, 28(%esp)
    223 
    224 	popa
    225 	ret
    226 
    227 /*
    228  * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
    229  *	Call with	%ah = 0x42
    230  *			%ds:%si = parameter block (data buffer address
    231  *				must be a real mode physical address).
    232  *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
    233  *	Return:
    234  *			%al = 0x0 on success; err code on failure
    235  */
    236 ENTRY(biosdisk_extread)
    237 	pusha
    238 
    239 	movl	%edx, %esi	# parameter block
    240 	movb	%al, %dl	# device
    241 
    242 	call	_C_LABEL(prot_to_real)	# enter real mode
    243 	.code16
    244 
    245 	push	%ds
    246 	movl	%esi, %eax
    247 	shrl	$4, %eax
    248 	movw	%ds, %bx
    249 	addw	%bx, %ax
    250 	movw	%ax, %ds
    251 	andw	$0xf, %si
    252 
    253 	movb	$0x42, %ah	# subfunction
    254 	int	$0x13
    255 	setc	%bl
    256 	movb	%ah, %bh	# save error code
    257 	pop	%ds
    258 
    259 	calll	_C_LABEL(real_to_prot) # back to protected mode
    260 	.code32
    261 
    262 	movzwl	%bx, %eax	# return value in %eax
    263 	movl	%eax, 28(%esp)
    264 
    265 	popa
    266 	ret
    267 
    268 ENTRY(biosdisk_getextinfo)
    269 	pusha
    270 
    271 	movl	%edx, %esi	# parameter block
    272 	movb	%al, %dl	# device
    273 
    274 	call	_C_LABEL(prot_to_real)	# enter real mode
    275 	.code16
    276 
    277 	push	%ds
    278 	movl	%esi, %eax
    279 	shrl	$4, %eax
    280 	andw	$0xf, %si
    281 	movw	%ds, %bx
    282 	addw	%bx, %ax
    283 	movw	%ax, %ds
    284 
    285 	movb	$0x48, %ah	# subfunction
    286 	int	$0x13
    287 	setc	%bl
    288 	pop	%ds
    289 
    290 	calll	_C_LABEL(real_to_prot) # back to protected mode
    291 	.code32
    292 
    293 	movzbl	%bl, %eax	# return value in %eax
    294 	movl	%eax, 28(%esp)
    295 
    296 	popa
    297 	ret
    298