1/* $NetBSD: bios_disk.S,v 1.18 2005/12/11 12:17:48 christos 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(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 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 * biosdisk_read(dev, cyl, head, sect, count, buff_addr); 107 * 108 * Note: On failure, you must reset the disk with biosdisk_reset() before 109 * sending another command. 110 */ 111ENTRY(biosdisk_read) 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 * biosdisk_getinfo(int dev): return a word that represents the 161 * max number of sectors, heads and cylinders for this device 162 */ 163ENTRY(biosdisk_getinfo) 164 pushl %ebp 165 movl %esp, %ebp 166 push %es 167 pushl %ebx 168 push %ecx 169 push %edx 170 push %esi 171 push %edi 172 173 movb 8(%ebp), %dl # diskinfo(drive #) 174 175 call _C_LABEL(prot_to_real) # enter real mode 176 .code16 177 178 push %dx # save drive # 179 movb $0x08, %ah # ask for disk info 180 int $0x13 181 pop %bx # restore drive # 182 jnc ok 183 184 testb $0x80, %bl # is it a hard disk? 185 jnz ok 186 187 /* 188 * Urk. Call failed. It is not supported for floppies by old BIOS's. 189 * Guess it's a 15-sector floppy. Initialize all the registers for 190 * documentation, although we only need head and sector counts. 191 */ 192 xorw %ax, %ax # set status to success 193# movb %ah, %bh # %bh = 0 194# movb $2, %bl # %bl bits 0-3 = drive type, 2 = 1.2M 195 movb $79, %ch # max track 196 movb $15, %cl # max sector 197 movb $1, %dh # max head 198# movb $1, %dl # # floppy drives installed 199 # es:di = parameter table 200 # carry = 0 201 202ok: 203 calll _C_LABEL(real_to_prot) # back to protected mode 204 .code32 205 206 /* form a longword representing all this gunk */ 207 shrl $8, %eax # clear unnecessary bits 208 shll $24, %eax 209 shll $16, %ecx # do the same for %ecx 210 shrl $8, %ecx 211 movb %dh, %cl # max head 212 orl %ecx, %eax # return value in %eax 213 214 pop %edi 215 pop %esi 216 pop %edx 217 pop %ecx 218 popl %ebx 219 pop %es 220 popl %ebp 221 ret 222 223/* 224 * int biosdisk_int13ext(int dev): 225 * check for availibility of int13 extensions. 226 */ 227ENTRY(biosdisk_int13ext) 228 pushl %ebp 229 movl %esp, %ebp 230 pushl %ebx 231 pushl %ecx 232 pushl %edx 233 pushl %esi 234 pushl %edi 235 236 movb 8(%ebp), %dl # drive # 237 movw $0x55aa, %bx 238 239 call _C_LABEL(prot_to_real) # enter real mode 240 .code16 241 242 movb $0x41, %ah # ask for disk info 243 int $0x13 244 setnc %dl 245 246 calll _C_LABEL(real_to_prot) # switch back 247 .code32 248 249 xorl %eax, %eax 250 movb %dl, %al # return value in %ax 251 252 cmpw $0xaa55, %bx 253 sete %dl 254 andb %dl, %al 255 256 andb %cl, %al 257 258 popl %edi 259 popl %esi 260 popl %edx 261 popl %ecx 262 popl %ebx 263 popl %ebp 264 ret 265 266/* 267 * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory 268 * Call with %ah = 0x42 269 * %ds:%si = parameter block (data buffer address 270 * must be a real mode physical address). 271 * %dl = drive (0x80 for hard disk, 0x0 for floppy disk) 272 * Return: 273 * %al = 0x0 on success; err code on failure 274 */ 275ENTRY(biosdisk_extread) 276 pushl %ebp 277 movl %esp, %ebp 278 pushl %ebx 279 push %ecx 280 push %edx 281 push %esi 282 push %edi 283 284 movb 8(%ebp), %dl # device 285 movl 12(%ebp), %esi # parameter block 286 287 call _C_LABEL(prot_to_real) # enter real mode 288 .code16 289 290 movl %esi, %eax 291 shrl $4, %eax 292 movw %ds, %bx 293 addw %bx, %ax 294 movw %ax, %ds 295 andw $0xf, %si 296 297 movb $0x42, %ah # subfunction 298 int $0x13 299 setc %bl 300 movb %ah, %bh # save error code 301 302 calll _C_LABEL(real_to_prot) # back to protected mode 303 .code32 304 305 xorl %eax, %eax 306 movw %bx, %ax # return value in %ax 307 308 pop %edi 309 pop %esi 310 pop %edx 311 pop %ecx 312 popl %ebx 313 popl %ebp 314 ret 315 316ENTRY(biosdisk_getextinfo) 317 pushl %ebp 318 movl %esp, %ebp 319 pushl %ebx 320 push %ecx 321 push %edx 322 push %esi 323 push %edi 324 325 movb 8(%ebp), %dl # device 326 movl 12(%ebp), %esi # parameter block 327 328 call _C_LABEL(prot_to_real) # enter real mode 329 .code16 330 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 342 calll _C_LABEL(real_to_prot) # back to protected mode 343 .code32 344 345 xorl %eax, %eax 346 movb %bl, %al # return value in %ax 347 348 pop %edi 349 pop %esi 350 pop %edx 351 pop %ecx 352 popl %ebx 353 popl %ebp 354 ret 355