summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authornyan <nyan@FreeBSD.org>2000-07-14 04:23:45 +0000
committernyan <nyan@FreeBSD.org>2000-07-14 04:23:45 +0000
commit9563771e2ec79d5dc1d43fd2a740d44043025260 (patch)
tree5659ef2fb43f334855164ca18d6de4efb265cfbc /sys
parent129319994023810b51cebbd4cd12452eebe071e5 (diff)
downloadFreeBSD-src-9563771e2ec79d5dc1d43fd2a740d44043025260.zip
FreeBSD-src-9563771e2ec79d5dc1d43fd2a740d44043025260.tar.gz
Merged from sys/boot/i386/libi386/biosdisk.c revision 1.31.
Diffstat (limited to 'sys')
-rw-r--r--sys/boot/pc98/libpc98/biosdisk.c123
1 files changed, 94 insertions, 29 deletions
diff --git a/sys/boot/pc98/libpc98/biosdisk.c b/sys/boot/pc98/libpc98/biosdisk.c
index e17240d..b0269a3 100644
--- a/sys/boot/pc98/libpc98/biosdisk.c
+++ b/sys/boot/pc98/libpc98/biosdisk.c
@@ -48,6 +48,7 @@
#include <btxv86.h>
#include "libi386.h"
+#define BIOS_NUMDRIVES 0x475
#define BIOSDISK_SECSIZE 512
#define BUFSIZE (1 * BIOSDISK_SECSIZE)
#define MAXBDDEV MAXDEV
@@ -75,7 +76,7 @@ struct open_disk {
#define BD_MODEINT13 0x0000
#define BD_MODEEDD1 0x0001
#define BD_MODEEDD3 0x0002
-#define BD_MODEMASK 0x0003
+#define BD_MODEMASK 0x0003
#define BD_FLOPPY 0x0004
#define BD_LABELOK 0x0008
#define BD_PARTTABOK 0x0010
@@ -161,24 +162,20 @@ bd_unit2bios(int unit)
/*
* Quiz the BIOS for disk devices, save a little info about them.
- *
- * XXX should we be consulting the BIOS equipment list, specifically
- * the value at 0x475?
*/
static int
bd_init(void)
{
+#ifdef PC98
int base, unit;
+ int da_drive=0, n=-0x10;
-#ifdef PC98
- int da_drive=0, n=-0x10;
/* sequence 0x90, 0x80, 0xa0 */
for (base = 0x90; base <= 0xa0; base += n, n += 0x30) {
for (unit = base; (nbdinfo < MAXBDDEV) || ((unit & 0x0f) < 4); unit++) {
bdinfo[nbdinfo].bd_unit = unit;
bdinfo[nbdinfo].bd_flags = (unit & 0xf0) == 0x90 ? BD_FLOPPY : 0;
- /* XXX add EDD probes */
if (!bd_int13probe(&bdinfo[nbdinfo])){
if (((unit & 0xf0) == 0x90 && (unit & 0x0f) < 4) ||
((unit & 0xf0) == 0xa0 && (unit & 0x0f) < 6))
@@ -206,13 +203,19 @@ bd_init(void)
}
}
#else
+ int base, unit, nfd = 0;
+
/* sequence 0, 0x80 */
for (base = 0; base <= 0x80; base += 0x80) {
for (unit = base; (nbdinfo < MAXBDDEV); unit++) {
+ /* check the BIOS equipment list for number of fixed disks */
+ if((base == 0x80) &&
+ (nfd >= *(unsigned short *)PTOV(BIOS_NUMDRIVES)))
+ break;
+
bdinfo[nbdinfo].bd_unit = unit;
bdinfo[nbdinfo].bd_flags = (unit < 0x80) ? BD_FLOPPY : 0;
- /* XXX add EDD probes */
if (!bd_int13probe(&bdinfo[nbdinfo]))
break;
@@ -220,6 +223,8 @@ bd_init(void)
printf("BIOS drive %c: is disk%d\n",
(unit < 0x80) ? ('A' + unit) : ('C' + unit - 0x80), nbdinfo);
nbdinfo++;
+ if (base == 0x80)
+ nfd++;
}
}
#endif
@@ -229,13 +234,12 @@ bd_init(void)
/*
* Try to detect a device supported by the legacy int13 BIOS
*/
-
static int
bd_int13probe(struct bdinfo *bd)
{
-
#ifdef PC98
int addr;
+
if (bd->bd_flags & BD_FLOPPY) {
addr = 0xa155c;
} else {
@@ -260,10 +264,23 @@ bd_int13probe(struct bdinfo *bd)
((v86.edx & 0xff) > (bd->bd_unit & 0x7f))) { /* unit # OK */
bd->bd_flags |= BD_MODEINT13;
bd->bd_type = v86.ebx & 0xff;
+
+ /* Determine if we can use EDD with this device. */
+ v86.eax = 0x4100;
+ v86.edx = bd->bd_unit;
+ v86.ebx = 0x55aa;
+ v86int();
+ if (!(v86.efl & 0x1) && /* carry clear */
+ ((v86.ebx & 0xffff) == 0xaa55) && /* signature */
+ (v86.ecx & 0x1)) { /* packets mode ok */
+ bd->bd_flags |= BD_MODEEDD1;
+ if(v86.eax & 0xff00 > 0x300)
+ bd->bd_flags |= BD_MODEEDD3;
+ }
return(1);
}
-#endif
return(0);
+#endif
}
/*
@@ -362,19 +379,28 @@ bd_printslice(struct open_disk *od, struct dos_partition *dp, char *prefix)
case DOSPTYP_EXT:
return;
case 0x01:
- sprintf(line, "%s: FAT-12\n", prefix);
+ sprintf(line, "%s: FAT-12 %.6dMB (%d - %d)\n", prefix,
+ dp->dp_size / 2048, /* 512-byte sector assumption */
+ dp->dp_start, dp->dp_start + dp->dp_size);
break;
case 0x04:
case 0x06:
case 0x0e:
- sprintf(line, "%s: FAT-16\n", prefix);
+ sprintf(line, "%s: FAT-16 %.6dMB (%d - %d)\n", prefix,
+ dp->dp_size / 2048, /* 512-byte sector assumption */
+ dp->dp_start, dp->dp_start + dp->dp_size);
break;
case 0x0b:
case 0x0c:
- sprintf(line, "%s: FAT-32\n", prefix);
+ sprintf(line, "%s: FAT-32 %.6dMB (%d - %d)\n", prefix,
+ dp->dp_size / 2048, /* 512-byte sector assumption */
+ dp->dp_start, dp->dp_start + dp->dp_size);
break;
default:
- sprintf(line, "%s: Unknown fs: 0x%x\n", prefix, dp->dp_typ);
+ sprintf(line, "%s: Unknown fs: 0x%x %.6dMB (%d - %d)\n",
+ prefix, dp->dp_typ,
+ dp->dp_size / 2048, /* 512-byte sector assumption */
+ dp->dp_start, dp->dp_start + dp->dp_size);
}
pager_output(line);
}
@@ -393,18 +419,21 @@ bd_printbsdslice(struct open_disk *od, int offset, char *prefix)
return;
lp =(struct disklabel *)(&buf[0]);
if (lp->d_magic != DISKMAGIC) {
- sprintf(line, "bad disklabel\n");
+ sprintf(line, "%s: FFS bad disklabel\n", prefix);
pager_output(line);
return;
}
/* Print partitions */
for (i = 0; i < lp->d_npartitions; i++) {
- if ((lp->d_partitions[i].p_fstype == FS_BSDFFS) || (lp->d_partitions[i].p_fstype == FS_SWAP) ||
+ if ((lp->d_partitions[i].p_fstype == FS_BSDFFS) ||
+ (lp->d_partitions[i].p_fstype == FS_SWAP) ||
+ (lp->d_partitions[i].p_fstype == FS_VINUM) ||
((lp->d_partitions[i].p_fstype == FS_UNUSED) &&
(od->od_flags & BD_FLOPPY) && (i == 0))) { /* Floppies often have bogus fstype, print 'a' */
sprintf(line, " %s%c: %s %.6dMB (%d - %d)\n", prefix, 'a' + i,
- (lp->d_partitions[i].p_fstype == FS_SWAP) ? "swap" : "FFS",
+ (lp->d_partitions[i].p_fstype == FS_SWAP) ? "swap" :
+ (lp->d_partitions[i].p_fstype == FS_VINUM) ? "vinum" : "FFS",
lp->d_partitions[i].p_size / 2048, /* 512-byte sector assumption */
lp->d_partitions[i].p_offset, lp->d_partitions[i].p_offset + lp->d_partitions[i].p_size);
pager_output(line);
@@ -531,8 +560,10 @@ bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev)
*/
bcopy(buf + DOSPARTOFF, &od->od_slicetab,
sizeof(struct dos_partition) * NDOSPART);
+#ifdef PC98
od->od_nslices = NDOSPART; /* extended slices start here */
-#ifndef PC98
+#else
+ od->od_nslices = 4; /* extended slices start here */
for (i = 0; i < NDOSPART; i++)
bd_checkextended(od, i);
#endif
@@ -960,9 +991,8 @@ bd_read(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest)
v86int();
}
- /* build request XXX support EDD requests too */
- v86.ctl = V86_FLAGS;
#ifdef PC98
+ v86.ctl = V86_FLAGS;
v86.addr = 0x1b;
if (od->od_flags & BD_FLOPPY) {
v86.eax = 0xd600 | od->od_unit;
@@ -976,18 +1006,53 @@ bd_read(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest)
v86.ebx = x * BIOSDISK_SECSIZE;
v86.es = VTOPSEG(xp);
v86.ebp = VTOPOFF(xp);
-#else
- v86.addr = 0x13;
- v86.eax = 0x200 | x;
- v86.ecx = ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec;
- v86.edx = (hd << 8) | od->od_unit;
- v86.es = VTOPSEG(xp);
- v86.ebx = VTOPOFF(xp);
-#endif
v86int();
result = (v86.efl & 0x1);
if (result == 0)
break;
+#else
+ 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;
+ break;
+ }
+ } else {
+ /* Use normal CHS addressing */
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0x200 | x;
+ v86.ecx = ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec;
+ v86.edx = (hd << 8) | od->od_unit;
+ v86.es = VTOPSEG(xp);
+ v86.ebx = VTOPOFF(xp);
+ v86int();
+ result = (v86.efl & 0x1);
+ if (result == 0)
+ break;
+ }
+#endif
}
#ifdef PC98
OpenPOWER on IntegriCloud