2 * Extended Boot Option ROM
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Copyright IBM Corporation, 2007
19 * Authors: Anthony Liguori <aliguori@us.ibm.com>
27 .byte (_end - _start) / 512
31 /* setup ds so we can access the IVT */
37 mov %eax, %cs:old_int19
39 /* install out int 19 handler */
40 movw $int19_handler, (0x19*4)
54 /* setup ds to access IVT */
66 1: /* hook int13: intb(0x404) == 1 */
67 /* save old int 13 to int 2c */
69 mov %eax, %cs:old_int13
71 /* install our int 13 handler */
72 movw $int13_handler, (0x13*4)
76 2: /* linux boot: intb(0x404) == 2 */
86 ljmp $0x9000 + 0x20, $0
88 3: /* fall through: inb(0x404) == 0 */
89 /* restore previous int $0x19 handler */
90 mov %cs:old_int19,%eax
100 #define FLAGS_CF 0x01
106 and $(~FLAGS_CF), %ax
126 mov %sp, %bp /* remember the current stack position */
141 mov %sp, %bp /* remember the current stack position */
179 mov %ax, 0(%bx) /* ax */
180 mov 0(%bp), %ax /* bx */
182 mov %cx, 4(%bx) /* cx */
183 mov %dx, 6(%bx) /* dx */
184 mov %si, 8(%bx) /* si */
185 mov %ds, 10(%bx) /* ds */
186 mov %es, 12(%bx) /* ds */
187 movw \value, 14(%bx) /* value */
231 add32: /* lo, hi, lo, hi */
235 movw 4(%bp), %cx /* hi */
236 movw 6(%bp), %dx /* lo */
246 mul32: /* lo, hi, lo, hi */
247 /* 10(%bp), 8(%bp), 6(%bp), 4(%bp) */
256 /* for (i = 0; i < 16;) */
298 /* this really should be a function, not a macro but i'm lazy */
299 .macro read_write_disk_sectors cmd
310 /* save nb_sectors */
339 movw $0, 0(%bx) /* read c,h,s */
344 mov 6(%bx), %ax /* total_sectors */
345 mov 2(%bp), %si /* *= heads */
347 add 4(%bp), %ax /* += sectors - 1 */
349 push 4(%bx) /* total_heads */
351 push 6(%bx) /* total_sectors */
356 push 0(%bp) /* cylinders */
371 movw \cmd, 0(%bx) /* read */
372 movw 6(%bp), %ax /* nb_sectors */
374 movw %es, 4(%bx) /* segment */
375 movw 8(%bp), %ax /* offset */
377 movw %dx, 8(%bx) /* sector */
403 read_write_disk_sectors $0x01
406 read_write_disk_sectors $0x02
408 read_disk_drive_parameters:
411 /* allocate memory for packet, pointer gets returned in bx */
415 movw $0, 0(%bx) /* cmd = 0, read c,h,s */
420 /* normalize sector value */
425 /* normalize cylinders */
428 /* normalize heads */
456 /* do this last since it's the most sensitive */
460 alternate_disk_reset:
465 read_disk_drive_size:
469 movw $0, 0(%bx) /* cmd = 0, read c,h,s */
474 /* cylinders - 1 to cx:dx */
504 check_if_extensions_present:
511 .macro extended_read_write_sectors cmd
522 movw \cmd, 0(%bp) /* read */
523 movw 2(%si), %ax /* nb_sectors */
525 movw 4(%si), %ax /* offset */
527 movw 6(%si), %ax /* segment */
529 movw 8(%si), %ax /* block */
551 extended_read_sectors:
552 extended_read_write_sectors $0x01
554 extended_write_sectors:
555 extended_read_write_sectors $0x02
557 get_extended_drive_parameters:
565 movw $0, 0(%bp) /* read c,h,s */
594 /* set total number of sectors */
604 /* number of bytes per sector */
618 terminate_disk_emulation:
635 call read_disk_sectors
640 call read_disk_drive_parameters
645 call read_disk_drive_size
650 call check_if_extensions_present
655 call extended_read_sectors
660 call get_extended_drive_parameters
665 call terminate_disk_emulation
670 call alternate_disk_reset
675 call write_disk_sectors
680 call extended_write_sectors
683 int $0x18 /* boot failed */