summaryrefslogtreecommitdiff
path: root/sys/arch/i386/stand/libsa
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/i386/stand/libsa')
-rw-r--r--sys/arch/i386/stand/libsa/biosdev.c37
-rw-r--r--sys/arch/i386/stand/libsa/dev_i386.c20
-rw-r--r--sys/arch/i386/stand/libsa/diskprobe.c93
-rw-r--r--sys/arch/i386/stand/libsa/libsa.h3
4 files changed, 136 insertions, 17 deletions
diff --git a/sys/arch/i386/stand/libsa/biosdev.c b/sys/arch/i386/stand/libsa/biosdev.c
index 4ad9aaa1f15..84a0387e1d4 100644
--- a/sys/arch/i386/stand/libsa/biosdev.c
+++ b/sys/arch/i386/stand/libsa/biosdev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: biosdev.c,v 1.68 2004/03/09 19:12:12 tom Exp $ */
+/* $OpenBSD: biosdev.c,v 1.69 2004/06/23 00:21:49 tom Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -34,6 +34,7 @@
#include <machine/tss.h>
#include <machine/biosvar.h>
#include <lib/libsa/saerrno.h>
+#include <isofs/cd9660/iso.h>
#include "disk.h"
#include "debug.h"
#include "libsa.h"
@@ -47,6 +48,7 @@ static int EDD_rw (int, int, u_int64_t, u_int32_t, void *);
extern int debug;
int bios_bootdev;
+int bios_cddev = -1; /* Set by srt0 if coming from CD */
#if 0
struct biosdisk {
@@ -241,17 +243,35 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf)
int dev = bd->bios_number;
int j, error;
void *bb;
+ int bbsize = nsect * DEV_BSIZE;
+
+ if (bd->flags & BDI_EL_TORITO) { /* It's a CD device */
+ dev &= 0xff; /* Mask out this flag bit */
- /* use a bounce buffer to not cross 64k DMA boundary */
- if ((((u_int32_t)buf) & ~0xffff) !=
- (((u_int32_t)buf + nsect * DEV_BSIZE) & ~0xffff)) {
+ /*
+ * sys/lib/libsa/cd9600.c converts 2,048-byte CD sectors
+ * to DEV_BSIZE blocks before calling the device strategy
+ * routine. However, the El Torito spec says that the
+ * BIOS will work in 2,048-byte sectors. So shift back.
+ */
+ off >>= (ISO_DEFAULT_BLOCK_SHIFT - DEV_BSHIFT);
+ nsect >>= (ISO_DEFAULT_BLOCK_SHIFT - DEV_BSHIFT);
+ }
+
+ /*
+ * Use a bounce buffer to not cross 64k DMA boundary, and to
+ * not access above 1 MB.
+ */
+ if (((((u_int32_t)buf) & ~0xffff) !=
+ (((u_int32_t)buf + bbsize) & ~0xffff)) ||
+ (((u_int32_t)buf) > 0x100000)) {
/*
* XXX we believe that all the io is buffered
* by fs routines, so no big reads anyway
*/
- bb = alloca(nsect * DEV_BSIZE);
+ bb = alloca(bbsize);
if (rw != F_READ)
- bcopy(buf, bb, nsect * DEV_BSIZE);
+ bcopy(buf, bb, bbsize);
} else
bb = buf;
@@ -302,7 +322,7 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf)
}
if (bb != buf && rw == F_READ)
- bcopy(bb, buf, nsect * DEV_BSIZE);
+ bcopy(bb, buf, bbsize);
#ifdef BIOS_DEBUG
if (debug) {
@@ -442,6 +462,9 @@ biosopen(struct open_file *f, ...)
break;
case 2: /* fd */
break;
+ case 6: /* cd */
+ biosdev = bios_bootdev & 0xff;
+ break;
default:
return ENXIO;
}
diff --git a/sys/arch/i386/stand/libsa/dev_i386.c b/sys/arch/i386/stand/libsa/dev_i386.c
index 45afe2243c7..4db4b1e0b6f 100644
--- a/sys/arch/i386/stand/libsa/dev_i386.c
+++ b/sys/arch/i386/stand/libsa/dev_i386.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dev_i386.c,v 1.28 2004/03/09 19:12:12 tom Exp $ */
+/* $OpenBSD: dev_i386.c,v 1.29 2004/06/23 00:21:49 tom Exp $ */
/*
* Copyright (c) 1996-1999 Michael Shalayeff
@@ -97,12 +97,18 @@ devboot(dev_t bootdev, char *p)
*p++ = '/';
*p++ = 'r';
#endif
- if (bootdev & 0x80)
- *p++ = 'h';
- else
- *p++ = 'f';
- *p++ = 'd';
- *p++ = '0' + (bootdev & 0x7f);
+ if (bootdev & 0x100) {
+ *p++ = 'c';
+ *p++ = 'd';
+ *p++ = '0';
+ } else {
+ if (bootdev & 0x80)
+ *p++ = 'h';
+ else
+ *p++ = 'f';
+ *p++ = 'd';
+ *p++ = '0' + (bootdev & 0x7f);
+ }
*p++ = 'a';
*p = '\0';
}
diff --git a/sys/arch/i386/stand/libsa/diskprobe.c b/sys/arch/i386/stand/libsa/diskprobe.c
index 27cc00c7d47..838117b6a7c 100644
--- a/sys/arch/i386/stand/libsa/diskprobe.c
+++ b/sys/arch/i386/stand/libsa/diskprobe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: diskprobe.c,v 1.26 2004/03/19 13:48:18 tom Exp $ */
+/* $OpenBSD: diskprobe.c,v 1.27 2004/06/23 00:21:49 tom Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -53,6 +53,8 @@ struct disklist_lh disklist;
struct diskinfo *bootdev_dip;
extern int debug;
+extern int bios_bootdev;
+extern int bios_cddev;
/* Probe for all BIOS floppies */
static void
@@ -205,6 +207,84 @@ diskprobe(void)
}
+void
+cdprobe(void)
+{
+ struct diskinfo *dip;
+ int cddev = bios_cddev & 0xff;
+
+ /* Another BIOS boot device... */
+
+ if (bios_cddev == -1) /* Not been set, so don't use */
+ return;
+
+ dip = alloc(sizeof(struct diskinfo));
+ bzero(dip, sizeof(*dip));
+
+#if 0
+ if (bios_getdiskinfo(cddev, &dip->bios_info)) {
+ printf(" <!cd0>"); /* XXX */
+ free(dip, 0);
+ return;
+ }
+#endif
+
+ printf(" cd0");
+
+ dip->bios_info.bios_number = cddev;
+ dip->bios_info.bios_edd = 1; /* Use the LBA calls */
+ dip->bios_info.flags |= BDI_GOODLABEL | BDI_EL_TORITO;
+ dip->bios_info.checksum = 0; /* just in case */
+ dip->bios_info.bsd_dev =
+ MAKEBOOTDEV(0, 0, 0, 0xff, RAW_PART);
+
+ /* Create an imaginary disk label */
+ dip->disklabel.d_secsize = 2048;
+ dip->disklabel.d_ntracks = 1;
+ dip->disklabel.d_nsectors = 100;
+ dip->disklabel.d_ncylinders = 1;
+ dip->disklabel.d_secpercyl = dip->disklabel.d_ntracks *
+ dip->disklabel.d_nsectors;
+ if (dip->disklabel.d_secpercyl == 0) {
+ dip->disklabel.d_secpercyl = 100;
+ /* as long as it's not 0, since readdisklabel divides by it */
+ }
+
+ strncpy(dip->disklabel.d_typename, "ATAPI CD-ROM",
+ sizeof(dip->disklabel.d_typename));
+ dip->disklabel.d_type = DTYPE_ATAPI;
+
+ strncpy(dip->disklabel.d_packname, "fictitious",
+ sizeof(dip->disklabel.d_packname));
+ dip->disklabel.d_secperunit = 100;
+ dip->disklabel.d_rpm = 300;
+ dip->disklabel.d_interleave = 1;
+ dip->disklabel.d_flags = D_REMOVABLE;
+
+ dip->disklabel.d_bbsize = 2048;
+ dip->disklabel.d_sbsize = 2048;
+
+ dip->disklabel.d_magic = DISKMAGIC;
+ dip->disklabel.d_magic2 = DISKMAGIC;
+ dip->disklabel.d_checksum = dkcksum(&dip->disklabel);
+
+ /* 'a' partition covering the "whole" disk */
+ dip->disklabel.d_partitions[0].p_offset = 0;
+ dip->disklabel.d_partitions[0].p_size = 100;
+ dip->disklabel.d_partitions[0].p_fstype = FS_UNUSED;
+
+ /* The raw partition is special */
+ dip->disklabel.d_partitions[RAW_PART].p_offset = 0;
+ dip->disklabel.d_partitions[RAW_PART].p_size = 100;
+ dip->disklabel.d_partitions[RAW_PART].p_fstype = FS_UNUSED;
+
+ dip->disklabel.d_npartitions = RAW_PART + 1;
+
+ /* Add to queue of disks */
+ TAILQ_INSERT_TAIL(&disklist, dip, list);
+}
+
+
/* Find info on given BIOS disk */
struct diskinfo *
dklookup(int dev)
@@ -227,9 +307,18 @@ dump_diskinfo(void)
for (dip = TAILQ_FIRST(&disklist); dip; dip = TAILQ_NEXT(dip, list)) {
bios_diskinfo_t *bdi = &dip->bios_info;
int d = bdi->bios_number;
+ int u = d & 0x7f;
+ char c;
+
+ if (bdi->flags & BDI_EL_TORITO) {
+ c = 'c';
+ u = 0;
+ } else {
+ c = (d & 0x80) ? 'h' : 'f';
+ }
printf("%cd%d\t0x%x\t%s\t%d\t%d\t%d\t0x%x\t0x%x\n",
- (d & 0x80)?'h':'f', d & 0x7F, d,
+ c, u, d,
(bdi->flags & BDI_BADLABEL)?"*none*":"label",
bdi->bios_cylinders, bdi->bios_heads, bdi->bios_sectors,
bdi->flags, bdi->checksum);
diff --git a/sys/arch/i386/stand/libsa/libsa.h b/sys/arch/i386/stand/libsa/libsa.h
index f2cae0987f1..2da7e66bd79 100644
--- a/sys/arch/i386/stand/libsa/libsa.h
+++ b/sys/arch/i386/stand/libsa/libsa.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: libsa.h,v 1.39 2004/03/19 13:48:18 tom Exp $ */
+/* $OpenBSD: libsa.h,v 1.40 2004/06/23 00:21:49 tom Exp $ */
/*
* Copyright (c) 1996-1999 Michael Shalayeff
@@ -49,6 +49,7 @@ void ps2probe(void);
void pciprobe(void);
void memprobe(void);
void diskprobe(void);
+void cdprobe(void);
void apmprobe(void);
void apmfixmem(void);
void dump_biosmem(bios_memmap_t *);