Home | History | Annotate | Line # | Download | only in lib
bios_disk.S revision 1.18.92.2
      1 /*	$NetBSD: bios_disk.S,v 1.18.92.2 2011/01/10 00:37:33 jym 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 	pushl	%ebp
     67 	movl	%esp, %ebp
     68 	pushl	%ebx
     69 	push	%edx
     70 	push	%edi
     71 
     72 	movb	8(%ebp), %dl	# device
     73 
     74 	call	_C_LABEL(prot_to_real)	# enter real mode
     75 	.code16
     76 
     77 	movb	$0x0, %ah	# subfunction
     78 	int	$0x13
     79 	setc	%bl
     80 	movb	%ah, %bh	# save error code
     81 
     82 	calll	_C_LABEL(real_to_prot) # back to protected mode
     83 	.code32
     84 
     85 	movzwl	%bx, %eax	# return value in %eax
     86 
     87 	pop	%edi
     88 	pop	%edx
     89 	popl	%ebx
     90 	popl	%ebp
     91 	ret
     92 
     93 /*
     94  * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
     95  *	Call with	%ah = 0x2
     96  *			%al = number of sectors
     97  *			%ch = cylinder
     98  *			%cl = sector
     99  *			%dh = head
    100  *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
    101  *			%es:%bx = segment:offset of buffer
    102  *	Return:
    103  *			%al = 0x0 on success; err code on failure
    104  *
    105  * biosdisk_read(dev, cyl, head, sect, count, buff_addr);
    106  *
    107  *  Note: On failure, you must reset the disk with biosdisk_reset() before
    108  *        sending another command.
    109  */
    110 ENTRY(biosdisk_read)
    111 	pushl	%ebp
    112 	movl	%esp, %ebp
    113 	pushl	%ebx
    114 	push	%ecx
    115 	push	%edx
    116 	push	%esi
    117 	push	%edi
    118 
    119 	movb	16(%ebp), %dh
    120 	movw	12(%ebp), %cx
    121 	xchgb	%ch, %cl	# cylinder; the highest 2 bits of cyl is in %cl
    122 	rorb	$2, %cl
    123 	movb	20(%ebp), %al
    124 	orb	%al, %cl
    125 	incb	%cl		# sector; sec starts from 1, not 0
    126 	movb	8(%ebp), %dl	# device
    127 	movl	28(%ebp), %ebx	# buffer address (may be >64k)
    128 	movb	24(%ebp), %al	# number of sectors
    129 
    130 	call	_C_LABEL(prot_to_real)	# enter real mode
    131 	.code16
    132 
    133 	push	%bx
    134 	shrl	$4, %ebx	# max segment
    135 	mov	%ds, %si
    136 	add	%si, %bx
    137 	mov	%bx, %es	# %es:%bx now valid buffer address
    138 	pop	%bx
    139 	and	$0xf, %bx	# and min offset - to avoid overrun
    140 
    141 	movb	$0x2, %ah	# subfunction
    142 	int	$0x13
    143 	setc	%al		# error code is in %ah
    144 
    145 	calll	_C_LABEL(real_to_prot) # back to protected mode
    146 	.code32
    147 
    148 	movzwl	%ax, %eax	# return value in %eax
    149 
    150 	pop	%edi
    151 	pop	%esi
    152 	pop	%edx
    153 	pop	%ecx
    154 	popl	%ebx
    155 	popl	%ebp
    156 	ret
    157 
    158 /*
    159  * biosdisk_getinfo(int dev):  return a word that represents the
    160  *	max number of sectors, heads and cylinders for this device
    161  */
    162 ENTRY(biosdisk_getinfo)
    163 	pushl	%ebp
    164 	movl	%esp, %ebp
    165 	push	%es
    166 	pushl	%ebx
    167 	push	%ecx
    168 	push	%edx
    169 	push	%esi
    170 	push	%edi
    171 
    172 	movb	8(%ebp), %dl		# diskinfo(drive #)
    173 
    174 	call	_C_LABEL(prot_to_real)	# enter real mode
    175 	.code16
    176 
    177 	push	%dx			# save drive #
    178 	movb	$0x08, %ah		# ask for disk info
    179 	int	$0x13
    180 	pop	%bx			# restore drive #
    181 	jnc	ok
    182 
    183 	testb	$0x80, %bl		# is it a hard disk?
    184 	jnz	ok
    185 
    186 	/*
    187 	 * Urk.  Call failed.  It is not supported for floppies by old BIOS's.
    188 	 * Guess it's a 15-sector floppy.  Initialize all the registers for
    189 	 * documentation, although we only need head and sector counts.
    190 	 */
    191 	xorw	%ax, %ax		# set status to success
    192 #	movb	%ah, %bh		# %bh = 0
    193 #	movb	$2, %bl			# %bl bits 0-3 = drive type, 2 = 1.2M
    194 	movb	$79, %ch		# max track
    195 	movb	$15, %cl		# max sector
    196 	movb	$1, %dh			# max head
    197 #	movb	$1, %dl			# # floppy drives installed
    198 	# es:di = parameter table
    199 	# carry = 0
    200 
    201 ok:
    202 	calll	_C_LABEL(real_to_prot)	# back to protected mode
    203 	.code32
    204 
    205 	/* form a longword representing all this gunk */
    206 	shrl	$8, %eax		# clear unnecessary bits
    207 	shll	$24, %eax
    208 	shll	$16, %ecx		# do the same for %ecx
    209 	shrl	$8, %ecx
    210 	movb	%dh, %cl		# max head
    211 	orl	%ecx, %eax		# return value in %eax
    212 
    213 	pop	%edi
    214 	pop	%esi
    215 	pop	%edx
    216 	pop	%ecx
    217 	popl	%ebx
    218 	pop	%es
    219 	popl	%ebp
    220 	ret
    221 
    222 /*
    223  * int biosdisk_int13ext(int dev):
    224  *	check for availibility of int13 extensions.
    225  */
    226 ENTRY(biosdisk_int13ext)
    227 	pushl	%ebp
    228 	movl	%esp, %ebp
    229 	pushl	%ebx
    230 	pushl	%ecx
    231 	pushl	%edx
    232 	pushl	%esi
    233 	pushl	%edi
    234 
    235 	movb	8(%ebp), %dl		# drive #
    236 	movw	$0x55aa, %bx
    237 
    238 	call	_C_LABEL(prot_to_real)	# enter real mode
    239 	.code16
    240 
    241 	movb	$0x41, %ah		# ask for disk info
    242 	int	$0x13
    243 	setnc	%dl
    244 
    245 	calll	_C_LABEL(real_to_prot)	# switch back
    246 	.code32
    247 
    248 	movzbl	%dl, %eax		# return value in %eax
    249 
    250 	cmpw	$0xaa55, %bx
    251 	sete	%dl
    252 	andb	%dl, %al
    253 
    254 	andb	%cl, %al
    255 
    256 	popl	%edi
    257 	popl	%esi
    258 	popl	%edx
    259 	popl	%ecx
    260 	popl	%ebx
    261 	popl	%ebp
    262 	ret
    263 
    264 /*
    265  * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
    266  *	Call with	%ah = 0x42
    267  *			%ds:%si = parameter block (data buffer address
    268  *				must be a real mode physical address).
    269  *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
    270  *	Return:
    271  *			%al = 0x0 on success; err code on failure
    272  */
    273 ENTRY(biosdisk_extread)
    274 	pushl	%ebp
    275 	movl	%esp, %ebp
    276 	pushl	%ebx
    277 	push	%ecx
    278 	push	%edx
    279 	push	%esi
    280 	push	%edi
    281 
    282 	movb	8(%ebp), %dl	# device
    283 	movl	12(%ebp), %esi	# parameter block
    284 
    285 	call	_C_LABEL(prot_to_real)	# enter real mode
    286 	.code16
    287 
    288 	push	%ds
    289 	movl	%esi, %eax
    290 	shrl	$4, %eax
    291 	movw	%ds, %bx
    292 	addw	%bx, %ax
    293 	movw	%ax, %ds
    294 	andw	$0xf, %si
    295 
    296 	movb	$0x42, %ah	# subfunction
    297 	int	$0x13
    298 	setc	%bl
    299 	movb	%ah, %bh	# save error code
    300 	pop	%ds
    301 
    302 	calll	_C_LABEL(real_to_prot) # back to protected mode
    303 	.code32
    304 
    305 	movzwl	%bx, %eax	# return value in %eax
    306 
    307 	pop	%edi
    308 	pop	%esi
    309 	pop	%edx
    310 	pop	%ecx
    311 	popl	%ebx
    312 	popl	%ebp
    313 	ret
    314 
    315 ENTRY(biosdisk_getextinfo)
    316 	pushl	%ebp
    317 	movl	%esp, %ebp
    318 	pushl	%ebx
    319 	push	%ecx
    320 	push	%edx
    321 	push	%esi
    322 	push	%edi
    323 
    324 	movb	8(%ebp), %dl	# device
    325 	movl	12(%ebp), %esi	# parameter block
    326 
    327 	call	_C_LABEL(prot_to_real)	# enter real mode
    328 	.code16
    329 
    330 	push	%ds
    331 	movl	%esi, %eax
    332 	shrl	$4, %eax
    333 	andw	$0xf, %si
    334 	movw	%ds, %bx
    335 	addw	%bx, %ax
    336 	movw	%ax, %ds
    337 
    338 	movb	$0x48, %ah	# subfunction
    339 	int	$0x13
    340 	setc	%bl
    341 	pop	%ds
    342 
    343 	calll	_C_LABEL(real_to_prot) # back to protected mode
    344 	.code32
    345 
    346 	movzbl	%bl, %eax	# return value in %eax
    347 
    348 	pop	%edi
    349 	pop	%esi
    350 	pop	%edx
    351 	pop	%ecx
    352 	popl	%ebx
    353 	popl	%ebp
    354 	ret
    355