diff options
Diffstat (limited to 'sys/arch/i386/stand/libsa')
-rw-r--r-- | sys/arch/i386/stand/libsa/biosdev.c | 37 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/dev_i386.c | 20 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/diskprobe.c | 93 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/libsa.h | 3 |
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 *); |