1
Index: seabios/optionrom/extboot.S
2
===================================================================
3
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4
+++ seabios/optionrom/extboot.S 2011-11-24 10:30:35.984542155 -0800
7
+ * Extended Boot Option ROM
9
+ * This program is free software; you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation; either version 2 of the License, or
12
+ * (at your option) any later version.
14
+ * This program is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ * GNU General Public License for more details.
19
+ * You should have received a copy of the GNU General Public License
20
+ * along with this program; if not, write to the Free Software
21
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23
+ * Copyright IBM Corporation, 2007
24
+ * Authors: Anthony Liguori <aliguori@us.ibm.com>
27
+#define OLD_INT19 (0x80 * 4) /* re-use INT 0x80 BASIC vector */
28
+#define OLD_INT13 (0x81 * 4) /* re-use INT 0x81 BASIC vector */
35
+ .byte (_end - _start) / 512
39
+ /* setup ds so we can access the IVT */
43
+ /* there is one more bootable HD */
46
+ /* save old int 19 */
48
+ mov %eax, (OLD_INT19)
50
+ /* install out int 19 handler */
51
+ movw $int19_handler, (0x19*4)
59
+ push %eax /* reserve space for lret */
66
+ /* setup ds to access IVT */
70
+ /* save old int 13 to int 2c */
72
+ mov %eax, (OLD_INT13)
74
+ /* install our int 13 handler */
75
+ movw $int13_handler, (0x13*4)
78
+ /* restore previous int $0x19 handler */
79
+ mov (OLD_INT19),%eax
82
+ /* write old handler as return address onto stack */
95
+#define FLAGS_CF 0x01
97
+/* The two macro below clear/set the carry flag to indicate the status
98
+ * of the interrupt execution. It is not enough to issue a clc/stc instruction,
99
+ * since the value of the flags register will be overwritten by whatever is
100
+ * in the stack frame
105
+ /* 8 = 2 (bp, just pushed) + 2 (ip) + 3 (real mode interrupt frame) */
106
+ and $(~FLAGS_CF), 8(%bp)
112
+ /* 8 = 2 (bp, just pushed) + 2 (ip) + 3 (real mode interrupt frame) */
113
+ or $(FLAGS_CF), 8(%bp)
117
+/* we clobber %bx */
121
+ mov %sp, %bp /* remember the current stack position */
134
+/* we clobber %bp */
135
+.macro allocbpa size
136
+ mov %sp, %bp /* remember the current stack position */
166
+.macro callout value
174
+ mov %ax, 0(%bx) /* ax */
175
+ mov 0(%bp), %ax /* bx */
177
+ mov %cx, 4(%bx) /* cx */
178
+ mov %dx, 6(%bx) /* dx */
179
+ mov %si, 8(%bx) /* si */
180
+ mov %ds, 10(%bx) /* ds */
181
+ mov %es, 12(%bx) /* ds */
182
+ movw \value, 14(%bx) /* value */
226
+add32: /* lo, hi, lo, hi */
230
+ movw 4(%bp), %cx /* hi */
231
+ movw 6(%bp), %dx /* lo */
241
+mul32: /* lo, hi, lo, hi */
242
+ /* 10(%bp), 8(%bp), 6(%bp), 4(%bp) */
251
+ /* for (i = 0; i < 16;) */
293
+/* this really should be a function, not a macro but i'm lazy */
294
+.macro read_write_disk_sectors cmd
305
+ /* save nb_sectors */
334
+ movw $0, 0(%bx) /* read c,h,s */
339
+ mov 6(%bx), %ax /* total_sectors */
340
+ mov 2(%bp), %si /* *= heads */
342
+ add 4(%bp), %ax /* += sectors - 1 */
344
+ push 4(%bx) /* total_heads */
346
+ push 6(%bx) /* total_sectors */
351
+ push 0(%bp) /* cylinders */
366
+ movw \cmd, 0(%bx) /* read */
367
+ movw 6(%bp), %ax /* nb_sectors */
369
+ movw %es, 4(%bx) /* segment */
370
+ movw 8(%bp), %ax /* offset */
372
+ movw %dx, 8(%bx) /* sector */
398
+ read_write_disk_sectors $0x01
401
+ read_write_disk_sectors $0x02
403
+read_disk_drive_parameters:
406
+ /* allocate memory for packet, pointer gets returned in bx */
409
+ /* issue command */
410
+ movw $0, 0(%bx) /* cmd = 0, read c,h,s */
415
+ /* normalize sector value */
420
+ /* normalize cylinders */
423
+ /* normalize heads */
451
+ /* do this last since it's the most sensitive */
455
+alternate_disk_reset:
460
+read_disk_drive_size:
464
+ movw $0, 0(%bx) /* cmd = 0, read c,h,s */
469
+ /* cylinders - 1 to cx:dx */
499
+check_if_extensions_present:
506
+.macro extended_read_write_sectors cmd
517
+ movw \cmd, 0(%bp) /* read */
518
+ movw 2(%si), %ax /* nb_sectors */
520
+ movw 4(%si), %ax /* offset */
522
+ movw 6(%si), %ax /* segment */
524
+ movw 8(%si), %ax /* block */
546
+extended_read_sectors:
547
+ extended_read_write_sectors $0x01
549
+extended_write_sectors:
550
+ extended_read_write_sectors $0x02
552
+get_extended_drive_parameters:
560
+ movw $0, 0(%bp) /* read c,h,s */
568
+ /* set flags to 2 */
589
+ /* set total number of sectors */
599
+ /* number of bytes per sector */
613
+terminate_disk_emulation:
622
+ /* write old handler as return address onto stack */
630
+ mov (OLD_INT13), %eax
644
+ call read_disk_sectors
649
+ call read_disk_drive_parameters
654
+ call read_disk_drive_size
659
+ call check_if_extensions_present
664
+ call extended_read_sectors
669
+ call get_extended_drive_parameters
674
+ call terminate_disk_emulation
679
+ call alternate_disk_reset
684
+ call write_disk_sectors
689
+ call extended_write_sectors
692
+ int $0x18 /* boot failed */