Last call for testing the new EDD-first boot code.
Matthew Dillon
dillon at apollo.backplane.com
Sat Sep 25 18:59:22 PDT 2004
Last call for testing. This is going to go in probably ~monday or so.
It changes the boot code to always try EDD (linear sector number based IO)
first and only fall back to track/sector/cylinder mode if EDD fails.
-Matt
Matthew Dillon
<dillon at xxxxxxxxxxxxx>
Index: boot/i386/boot2/boot1.S
===================================================================
RCS file: /cvs/src/sys/boot/i386/boot2/boot1.S,v
retrieving revision 1.8
diff -u -r1.8 boot1.S
--- boot/i386/boot2/boot1.S 27 Jul 2004 19:37:17 -0000 1.8
+++ boot/i386/boot2/boot1.S 17 Sep 2004 20:40:59 -0000
@@ -314,8 +314,43 @@
//
// %dl - byte - drive number
// stack - 10 bytes - EDD Packet
-//
-read: push %dx // Save
+
+read:
+ /*
+ * Try EDD mode first. If not enabled or no BIOS support
+ * exists, fall back to CHS mode.
+ */
+ testb $FL_PACKET,%cs:BOOT1_ORIGIN+flags-start
+ jz read.1
+
+ /*
+ * BIOS: check extensions present
+ */
+ mov $0x55aa,%bx
+ push %dx
+ movb $0x41,%ah
+ int $0x13
+ pop %dx
+ jc read.1 /* BIOS error return */
+ cmp $0xaa55,%bx /* check for proper magic */
+ jne read.1
+ testb $0x1,%cl /* packet interface support? */
+ jz read.1
+
+ /*
+ * Issue packet command.
+ * BIOS: Extended read command
+ */
+ mov %bp,%si
+ movb $0x42,%ah
+ int $0x13
+ retw
+
+ /*
+ * Fallback to CHS mode
+ */
+read.1:
+ push %dx // Save
movb $0x8,%ah // BIOS: Get drive
int $0x13 // parameters
movb %dh,%ch // Max head number
@@ -338,7 +373,7 @@
pop %dx // Restore
cmpl $0x3ff,%eax // Cylinder number supportable?
sti // Enable interrupts
- ja read.7 // No, try EDD
+ ja ereturn // No, failed
xchgb %al,%ah // Set up cylinder
rorb $0x2,%al // number
orb %ch,%al // Merge
@@ -374,24 +409,8 @@
read.5: shlb %bl // buffer
add %bl,0x5(%bp) // pointer,
sub %al,0x2(%bp) // block count
- ja read // If not done
+ ja read.1 // If not done
read.6: retw // To caller
-read.7: testb $FL_PACKET,%cs:BOOT1_ORIGIN+flags-start // LBA support enabled?
- jz ereturn // No, so return an error
- mov $0x55aa,%bx // Magic
- push %dx // Save
- movb $0x41,%ah // BIOS: Check
- int $0x13 // extensions present
- pop %dx // Restore
- jc return // If error, return an error
- cmp $0xaa55,%bx // Magic?
- jne ereturn // No, so return an error
- testb $0x1,%cl // Packet interface?
- jz ereturn // No, so return an error
- mov %bp,%si // Disk packet
- movb $0x42,%ah // BIOS: Extended
- int $0x13 // read
- retw // To caller
// Messages
Index: boot/i386/libi386/biosdisk.c
===================================================================
RCS file: /cvs/src/sys/boot/i386/libi386/biosdisk.c,v
retrieving revision 1.6
diff -u -r1.6 biosdisk.c
--- boot/i386/libi386/biosdisk.c 21 Jun 2004 03:38:52 -0000 1.6
+++ boot/i386/libi386/biosdisk.c 17 Sep 2004 20:40:59 -0000
@@ -891,9 +891,14 @@
/* correct sector number for 1-based BIOS numbering */
sec++;
- /* Loop retrying the operation a couple of times. The BIOS may also retry. */
+ /*
+ * Loop retrying the operation a couple of times. The BIOS may also
+ * retry.
+ */
for (retry = 0; retry < 3; retry++) {
- /* if retrying, reset the drive */
+ /*
+ * If retrying, reset the drive.
+ */
if (retry > 0) {
v86.ctl = V86_FLAGS;
v86.addr = 0x13;
@@ -902,34 +907,33 @@
v86int();
}
- if(cyl > 1023) {
- /* use EDD if the disk supports it, otherwise, return error */
- if(od->od_flags & BD_MODEEDD1) {
- static unsigned short packet[8];
-
- packet[0] = 0x10;
- packet[1] = x;
- packet[2] = VTOPOFF(xp);
- packet[3] = VTOPSEG(xp);
- packet[4] = dblk & 0xffff;
- packet[5] = dblk >> 16;
- packet[6] = 0;
- packet[7] = 0;
- v86.ctl = V86_FLAGS;
- v86.addr = 0x13;
- v86.eax = 0x4200;
- v86.edx = od->od_unit;
- v86.ds = VTOPSEG(packet);
- v86.esi = VTOPOFF(packet);
- v86int();
- result = (v86.efl & 0x1);
- if(result == 0)
- break;
- } else {
- result = 1;
+ /*
+ * Always use EDD if the disk supports it, otherwise fall back
+ * to CHS mode (returning an error if the cylinder number is
+ * too large).
+ */
+ if (od->od_flags & BD_MODEEDD1) {
+ static unsigned short packet[8];
+
+ packet[0] = 0x10;
+ packet[1] = x;
+ packet[2] = VTOPOFF(xp);
+ packet[3] = VTOPSEG(xp);
+ packet[4] = dblk & 0xffff;
+ packet[5] = dblk >> 16;
+ packet[6] = 0;
+ packet[7] = 0;
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0x4200;
+ v86.edx = od->od_unit;
+ v86.ds = VTOPSEG(packet);
+ v86.esi = VTOPOFF(packet);
+ v86int();
+ result = (v86.efl & 0x1);
+ if (result == 0)
break;
- }
- } else {
+ } else if (cyl < 1024) {
/* Use normal CHS addressing */
v86.ctl = V86_FLAGS;
v86.addr = 0x13;
@@ -941,7 +945,10 @@
v86int();
result = (v86.efl & 0x1);
if (result == 0)
- break;
+ break;
+ } else {
+ result = 1;
+ break;
}
}
@@ -1034,9 +1041,14 @@
dblk += x;
resid -= x;
- /* Loop retrying the operation a couple of times. The BIOS may also retry. */
+ /*
+ * Loop retrying the operation a couple of times. The BIOS may also
+ * retry.
+ */
for (retry = 0; retry < 3; retry++) {
- /* if retrying, reset the drive */
+ /*
+ * If retrying, reset the drive.
+ */
if (retry > 0) {
v86.ctl = V86_FLAGS;
v86.addr = 0x13;
@@ -1044,36 +1056,35 @@
v86.edx = od->od_unit;
v86int();
}
-
- if(cyl > 1023) {
- /* use EDD if the disk supports it, otherwise, return error */
- if(od->od_flags & BD_MODEEDD1) {
- static unsigned short packet[8];
-
- packet[0] = 0x10;
- packet[1] = x;
- packet[2] = VTOPOFF(xp);
- packet[3] = VTOPSEG(xp);
- packet[4] = dblk & 0xffff;
- packet[5] = dblk >> 16;
- packet[6] = 0;
- packet[7] = 0;
- v86.ctl = V86_FLAGS;
- v86.addr = 0x13;
- /* Should we Write with verify ?? 0x4302 ? */
- v86.eax = 0x4300;
- v86.edx = od->od_unit;
- v86.ds = VTOPSEG(packet);
- v86.esi = VTOPOFF(packet);
- v86int();
- result = (v86.efl & 0x1);
- if(result == 0)
- break;
- } else {
- result = 1;
+
+ /*
+ * Always use EDD if the disk supports it, otherwise fall back
+ * to CHS mode (returning an error if the cylinder number is
+ * too large).
+ */
+ if (od->od_flags & BD_MODEEDD1) {
+ static unsigned short packet[8];
+
+ packet[0] = 0x10;
+ packet[1] = x;
+ packet[2] = VTOPOFF(xp);
+ packet[3] = VTOPSEG(xp);
+ packet[4] = dblk & 0xffff;
+ packet[5] = dblk >> 16;
+ packet[6] = 0;
+ packet[7] = 0;
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ /* Should we Write with verify ?? 0x4302 ? */
+ v86.eax = 0x4300;
+ v86.edx = od->od_unit;
+ v86.ds = VTOPSEG(packet);
+ v86.esi = VTOPOFF(packet);
+ v86int();
+ result = (v86.efl & 0x1);
+ if (result == 0)
break;
- }
- } else {
+ } else if (cyl < 1024) {
/* Use normal CHS addressing */
v86.ctl = V86_FLAGS;
v86.addr = 0x13;
@@ -1085,7 +1096,10 @@
v86int();
result = (v86.efl & 0x1);
if (result == 0)
- break;
+ break;
+ } else {
+ result = 1;
+ break;
}
}
More information about the Kernel
mailing list