1/* $NetBSD: bios_disk.S,v 1.13 2003/04/16 12:45:10 dsl Exp $ */ 2 3/* 4 * Ported to boot 386BSD by Julian Elischer (julian@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@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 37Permission to use, copy, modify, and distribute this software and 38its documentation for any purpose and without fee is hereby 39granted, provided that the above copyright notice appears in all 40copies and that both the copyright notice and this permission notice 41appear in supporting documentation, and that the name of Intel 42not be used in advertising or publicity pertaining to distribution 43of the software without specific, written prior permission. 44 45INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 46INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, 47IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 48CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 49LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 50NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 51WITH 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*/ 65ENTRY(biosdiskreset) 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 xorl %eax, %eax 86 movw %bx, %ax # return value in %ax 87 88 pop %edi 89 pop %edx 90 popl %ebx 91 popl %ebp 92 ret 93 94/* 95# BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory 96# Call with %ah = 0x2 97# %al = number of sectors 98# %ch = cylinder 99# %cl = sector 100# %dh = head 101# %dl = drive (0x80 for hard disk, 0x0 for floppy disk) 102# %es:%bx = segment:offset of buffer 103# Return: 104# %al = 0x0 on success; err code on failure 105# 106# biosread( dev, cyl, head, sect, count, buff_addr ); 107# 108# Note: On failure, you must reset the disk with biosdiskreset() before 109# sending another command. 110*/ 111ENTRY(biosread) 112 pushl %ebp 113 movl %esp, %ebp 114 pushl %ebx 115 push %ecx 116 push %edx 117 push %esi 118 push %edi 119 120 movb 16(%ebp), %dh 121 movw 12(%ebp), %cx 122 xchgb %ch, %cl # cylinder; the highest 2 bits of cyl is in %cl 123 rorb $2, %cl 124 movb 20(%ebp), %al 125 orb %al, %cl 126 incb %cl # sector; sec starts from 1, not 0 127 movb 8(%ebp), %dl # device 128 movl 28(%ebp), %ebx # buffer address (may be >64k) 129 movb 24(%ebp), %al # number of sectors 130 131 call _C_LABEL(prot_to_real) # enter real mode 132 .code16 133 134 push %bx 135 shrl $4, %ebx # max segment 136 mov %ds, %si 137 add %si, %bx 138 mov %bx, %es # %es:%bx now valid buffer address 139 pop %bx 140 and $0xf, %bx # and min offset - to avoid overrun 141 142 movb $0x2, %ah # subfunction 143 int $0x13 144 setc %al # error code is in %ah 145 146 calll _C_LABEL(real_to_prot) # back to protected mode 147 .code32 148 149 andl $0xffff, %eax 150 151 pop %edi 152 pop %esi 153 pop %edx 154 pop %ecx 155 popl %ebx 156 popl %ebp 157 ret 158 159/* 160# 161# get_diskinfo(): return a word that represents the 162# max number of sectors, heads and cylinders for this device 163# 164*/ 165 166ENTRY(get_diskinfo) 167 pushl %ebp 168 movl %esp, %ebp 169 push %es 170 pushl %ebx 171 push %ecx 172 push %edx 173 push %esi 174 push %edi 175 176 movb 8(%ebp), %dl # diskinfo(drive #) 177 178 call _C_LABEL(prot_to_real) # enter real mode 179 .code16 180 181 movb $0x08, %ah # ask for disk info 182 int $0x13 183 jnc ok 184 185 /* 186 * Urk. Call failed. It is not supported for floppies by old BIOS's. 187 * Guess it's a 15-sector floppy. Initialize all the registers for 188 * documentation, although we only need head and sector counts. 189 */ 190# subb %ah, %ah # %ax = 0 191# movb %ah, %bh # %bh = 0 192# movb $2, %bl # %bl bits 0-3 = drive type, 2 = 1.2M 193 movb $79, %ch # max track 194 movb $15, %cl # max sector 195 movb $1, %dh # max head 196# movb $1, %dl # # floppy drives installed 197 # es:di = parameter table 198 # carry = 0 199 200ok: 201 calll _C_LABEL(real_to_prot) # back to protected mode 202 .code32 203 204 /* form a longword representing all this gunk */ 205 shll $8, %ecx 206 movb %dh, %cl 207 208 movl %ecx, %eax 209 210 pop %edi 211 pop %esi 212 pop %edx 213 pop %ecx 214 popl %ebx 215 pop %es 216 popl %ebp 217 ret 218 219/* 220# int13_extension: check for availibility of int13 extensions. 221*/ 222 223ENTRY(int13_extension) 224 pushl %ebp 225 movl %esp, %ebp 226 pushl %ebx 227 pushl %ecx 228 pushl %edx 229 pushl %esi 230 pushl %edi 231 232 movb 8(%ebp), %dl # drive # 233 movw $0x55aa, %bx 234 235 call _C_LABEL(prot_to_real) # enter real mode 236 .code16 237 238 movb $0x41, %ah # ask for disk info 239 int $0x13 240 setnc %dl 241 242 calll _C_LABEL(real_to_prot) # switch back 243 .code32 244 245 xorl %eax, %eax 246 movb %dl, %al # return value in %ax 247 248 cmpw $0xaa55, %bx 249 sete %dl 250 andb %dl, %al 251 252 andb %cl, %al 253 254 popl %edi 255 popl %esi 256 popl %edx 257 popl %ecx 258 popl %ebx 259 popl %ebp 260 ret 261 262/* 263# BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory 264# Call with %ah = 0x42 265# %ds:%si = parameter block (data buffer address 266# must be a real mode physical address). 267# %dl = drive (0x80 for hard disk, 0x0 for floppy disk) 268# Return: 269# %al = 0x0 on success; err code on failure 270*/ 271ENTRY(biosextread) 272 pushl %ebp 273 movl %esp, %ebp 274 pushl %ebx 275 push %ecx 276 push %edx 277 push %esi 278 push %edi 279 280 movb 8(%ebp), %dl # device 281 movl 12(%ebp), %esi # parameter block 282 283 call _C_LABEL(prot_to_real) # enter real mode 284 .code16 285 286 movl %esi, %eax 287 shrl $4, %eax 288 movw %ds, %bx 289 addw %bx, %ax 290 movw %ax, %ds 291 andw $0xf, %si 292 293 movb $0x42, %ah # subfunction 294 int $0x13 295 setc %bl 296 movb %ah, %bh # save error code 297 298 calll _C_LABEL(real_to_prot) # back to protected mode 299 .code32 300 301 xorl %eax, %eax 302 movw %bx, %ax # return value in %ax 303 304 pop %edi 305 pop %esi 306 pop %edx 307 pop %ecx 308 popl %ebx 309 popl %ebp 310 ret 311 312ENTRY(int13_getextinfo) 313 pushl %ebp 314 movl %esp, %ebp 315 pushl %ebx 316 push %ecx 317 push %edx 318 push %esi 319 push %edi 320 321 movb 8(%ebp), %dl # device 322 movl 12(%ebp), %esi # parameter block 323 324 call _C_LABEL(prot_to_real) # enter real mode 325 .code16 326 327 movl %esi, %eax 328 shrl $4, %eax 329 andw $0xf, %si 330 movw %ds, %bx 331 addw %bx, %ax 332 movw %ax, %ds 333 334 movb $0x48, %ah # subfunction 335 int $0x13 336 setc %bl 337 338 calll _C_LABEL(real_to_prot) # back to protected mode 339 .code32 340 341 xorl %eax, %eax 342 movb %bl, %al # return value in %ax 343 344 pop %edi 345 pop %esi 346 pop %edx 347 pop %ecx 348 popl %ebx 349 popl %ebp 350 ret 351