aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2014-05-10 01:20:46 -0400
committerKevin O'Connor <kevin@koconnor.net>2014-06-04 11:06:58 -0400
commit02f7676421af87f59e0b8e039fb7f13aaecd0b2b (patch)
tree634a221e7d1fc149d1955f2e5a2906119ed923b2
parent9e735bbd1d45b41319bb27358c3d2e8079c9786a (diff)
downloadseabios-02f7676421af87f59e0b8e039fb7f13aaecd0b2b.tar.gz
cdemu: store internal cdemu fields in standard "el-torito" spec format.
Store the fields necessary to export the "el-torito" spec information directly in an internal copy of the "el-torito" struct. This simplifies the interface and obviates the need for an internal home grown struct with the same info. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--src/block.h15
-rw-r--r--src/boot.c2
-rw-r--r--src/cdrom.c72
-rw-r--r--src/disk.c15
-rw-r--r--src/std/disk.h8
-rw-r--r--src/util.h2
6 files changed, 38 insertions, 76 deletions
diff --git a/src/block.h b/src/block.h
index c870e138..945e6fe1 100644
--- a/src/block.h
+++ b/src/block.h
@@ -36,21 +36,6 @@ struct chs_s {
u16 pad;
};
-// ElTorito Device Emulation data
-struct cdemu_s {
- struct drive_s *emulated_drive_gf;
- u32 ilba;
- u16 buffer_segment;
- u16 load_segment;
- u16 sector_count;
- u8 active;
- u8 media;
- u8 emulated_extdrive;
-
- // Virtual device
- struct chs_s lchs;
-};
-
struct drive_s {
u8 type; // Driver type (DTYPE_*)
u8 floppy_type; // Type of floppy (only for floppy drives).
diff --git a/src/boot.c b/src/boot.c
index 133e2063..9be8b2a2 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -643,7 +643,7 @@ boot_cdrom(struct drive_s *drive_g)
return;
}
- u8 bootdrv = CDEmu.emulated_extdrive;
+ u8 bootdrv = CDEmu.emulated_drive;
u16 bootseg = CDEmu.load_segment;
/* Canonicalize bootseg:bootip */
u16 bootip = (bootseg & 0x0fff) << 4;
diff --git a/src/cdrom.c b/src/cdrom.c
index ff419c0f..f0d8a1ae 100644
--- a/src/cdrom.c
+++ b/src/cdrom.c
@@ -24,13 +24,14 @@ u8 CDRom_locks[BUILD_MAX_EXTDRIVE] VARLOW;
* CD emulation
****************************************************************/
-struct cdemu_s CDEmu VARLOW;
+struct eltorito_s CDEmu VARLOW = { .size=sizeof(CDEmu) };
+struct drive_s *emulated_drive_gf VARLOW;
struct drive_s *cdemu_drive_gf VARFSEG;
static int
cdemu_read(struct disk_op_s *op)
{
- struct drive_s *drive_gf = GET_LOW(CDEmu.emulated_drive_gf);
+ struct drive_s *drive_gf = GET_LOW(emulated_drive_gf);
struct disk_op_s dop;
dop.drive_gf = drive_gf;
dop.command = op->command;
@@ -131,35 +132,16 @@ cdrom_prepboot(void)
drive->sectors = (u64)-1;
}
-#define SET_INT13ET(regs,var,val) \
- SET_FARVAR((regs)->ds, ((struct eltorito_s*)((regs)->si+0))->var, (val))
-
// ElTorito - Terminate disk emu
void
cdemu_134b(struct bregs *regs)
{
- // FIXME ElTorito Hardcoded
- SET_INT13ET(regs, size, 0x13);
- SET_INT13ET(regs, media, GET_LOW(CDEmu.media));
- SET_INT13ET(regs, emulated_drive, GET_LOW(CDEmu.emulated_extdrive));
- struct drive_s *drive_gf = GET_LOW(CDEmu.emulated_drive_gf);
- u8 cntl_id = 0;
- if (drive_gf)
- cntl_id = GET_GLOBALFLAT(drive_gf->cntl_id);
- SET_INT13ET(regs, controller_index, cntl_id / 2);
- SET_INT13ET(regs, device_spec, cntl_id % 2);
- SET_INT13ET(regs, ilba, GET_LOW(CDEmu.ilba));
- SET_INT13ET(regs, buffer_segment, GET_LOW(CDEmu.buffer_segment));
- SET_INT13ET(regs, load_segment, GET_LOW(CDEmu.load_segment));
- SET_INT13ET(regs, sector_count, GET_LOW(CDEmu.sector_count));
- SET_INT13ET(regs, cylinders, GET_LOW(CDEmu.lchs.cylinder));
- SET_INT13ET(regs, sectors, GET_LOW(CDEmu.lchs.sector));
- SET_INT13ET(regs, heads, GET_LOW(CDEmu.lchs.head));
+ memcpy_far(regs->ds, (void*)(regs->si+0), SEG_LOW, &CDEmu, sizeof(CDEmu));
// If we have to terminate emulation
if (regs->al == 0x00) {
// FIXME ElTorito Various. Should be handled accordingly to spec
- SET_LOW(CDEmu.active, 0x00); // bye bye
+ SET_LOW(CDEmu.media, 0x00); // bye bye
// XXX - update floppy/hd count.
}
@@ -226,10 +208,9 @@ cdrom_boot(struct drive_s *drive)
if (buffer[0x20] != 0x88)
return 11; // Bootable
+ // Fill in el-torito cdrom emulation fields.
+ emulated_drive_gf = drive;
u8 media = buffer[0x21];
- CDEmu.media = media;
-
- CDEmu.emulated_drive_gf = dop.drive_gf;
u16 boot_segment = *(u16*)&buffer[0x22];
if (!boot_segment)
@@ -243,6 +224,9 @@ cdrom_boot(struct drive_s *drive)
lba = *(u32*)&buffer[0x28];
CDEmu.ilba = lba;
+ CDEmu.controller_index = drive->cntl_id / 2;
+ CDEmu.device_spec = drive->cntl_id % 2;
+
// And we read the image in memory
dop.lba = lba;
dop.count = DIV_ROUND_UP(nbsectors, 4);
@@ -253,7 +237,7 @@ cdrom_boot(struct drive_s *drive)
if (media == 0) {
// No emulation requested - return success.
- CDEmu.emulated_extdrive = EXTSTART_CD + cdid;
+ CDEmu.emulated_drive = EXTSTART_CD + cdid;
return 0;
}
@@ -265,45 +249,39 @@ cdrom_boot(struct drive_s *drive)
// number of devices
if (media < 4) {
// Floppy emulation
- CDEmu.emulated_extdrive = 0x00;
+ CDEmu.emulated_drive = 0x00;
// XXX - get and set actual floppy count.
set_equipment_flags(0x41, 0x41);
switch (media) {
case 0x01: // 1.2M floppy
- CDEmu.lchs.sector = 15;
- CDEmu.lchs.cylinder = 80;
- CDEmu.lchs.head = 2;
+ CDEmu.chs.sptcyl = 15;
+ CDEmu.chs.cyllow = 79;
+ CDEmu.chs.heads = 1;
break;
case 0x02: // 1.44M floppy
- CDEmu.lchs.sector = 18;
- CDEmu.lchs.cylinder = 80;
- CDEmu.lchs.head = 2;
+ CDEmu.chs.sptcyl = 18;
+ CDEmu.chs.cyllow = 79;
+ CDEmu.chs.heads = 1;
break;
case 0x03: // 2.88M floppy
- CDEmu.lchs.sector = 36;
- CDEmu.lchs.cylinder = 80;
- CDEmu.lchs.head = 2;
+ CDEmu.chs.sptcyl = 36;
+ CDEmu.chs.cyllow = 79;
+ CDEmu.chs.heads = 1;
break;
}
} else {
// Harddrive emulation
- CDEmu.emulated_extdrive = 0x80;
+ CDEmu.emulated_drive = 0x80;
SET_BDA(hdcount, GET_BDA(hdcount) + 1);
// Peak at partition table to get chs.
- struct mbr_s *mbr = (void*)0;
- u8 sptcyl = GET_FARVAR(boot_segment, mbr->partitions[0].last.sptcyl);
- u8 cyllow = GET_FARVAR(boot_segment, mbr->partitions[0].last.cyllow);
- u8 heads = GET_FARVAR(boot_segment, mbr->partitions[0].last.heads);
-
- CDEmu.lchs.sector = sptcyl & 0x3f;
- CDEmu.lchs.cylinder = ((sptcyl<<2)&0x300) + cyllow + 1;
- CDEmu.lchs.head = heads + 1;
+ struct mbr_s *mbr = MAKE_FLATPTR(boot_segment, 0);
+ CDEmu.chs = mbr->partitions[0].last;
}
// everything is ok, so from now on, the emulation is active
- CDEmu.active = 0x01;
+ CDEmu.media = media;
dprintf(6, "cdemu media=%d\n", media);
return 0;
diff --git a/src/disk.c b/src/disk.c
index 7e42103c..635d7b9a 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -41,9 +41,10 @@ getLCHS(struct drive_s *drive_gf)
// populate the geometry directly in the driveid because the
// geometry is only known after the bios segment is made
// read-only).
- res.cylinder = GET_LOW(CDEmu.lchs.cylinder);
- res.head = GET_LOW(CDEmu.lchs.head);
- res.sector = GET_LOW(CDEmu.lchs.sector);
+ u8 sptcyl = GET_LOW(CDEmu.chs.sptcyl);
+ res.cylinder = GET_LOW(CDEmu.chs.cyllow) + ((sptcyl << 2) & 0x300) + 1;
+ res.head = GET_LOW(CDEmu.chs.heads) + 1;
+ res.sector = sptcyl & 0x3f;
return res;
}
res.cylinder = GET_GLOBALFLAT(drive_gf->lchs.cylinder);
@@ -238,8 +239,8 @@ disk_1308(struct bregs *regs, struct drive_s *drive_gf)
return;
}
- if (CONFIG_CDROM_EMU && GET_LOW(CDEmu.active)) {
- u8 emudrive = GET_LOW(CDEmu.emulated_extdrive);
+ if (CONFIG_CDROM_EMU && GET_LOW(CDEmu.media)) {
+ u8 emudrive = GET_LOW(CDEmu.emulated_drive);
if (((emudrive ^ regs->dl) & 0x80) == 0)
// Note extra drive due to emulation.
count++;
@@ -663,8 +664,8 @@ handle_13(struct bregs *regs)
cdemu_134b(regs);
return;
}
- if (GET_LOW(CDEmu.active)) {
- u8 emudrive = GET_LOW(CDEmu.emulated_extdrive);
+ if (GET_LOW(CDEmu.media)) {
+ u8 emudrive = GET_LOW(CDEmu.emulated_drive);
if (extdrive == emudrive) {
// Access to an emulated drive.
struct drive_s *cdemu_gf = GET_GLOBAL(cdemu_drive_gf);
diff --git a/src/std/disk.h b/src/std/disk.h
index b2576d93..63971089 100644
--- a/src/std/disk.h
+++ b/src/std/disk.h
@@ -129,7 +129,7 @@ struct packed_chs_s {
u8 heads;
u8 sptcyl;
u8 cyllow;
-};
+} PACKED;
struct partition_s {
u8 status;
@@ -169,9 +169,7 @@ struct eltorito_s {
u16 buffer_segment;
u16 load_segment;
u16 sector_count;
- u8 cylinders;
- u8 sectors;
- u8 heads;
-};
+ struct packed_chs_s chs;
+} PACKED;
#endif // disk.h
diff --git a/src/util.h b/src/util.h
index b54271b6..74b58f4b 100644
--- a/src/util.h
+++ b/src/util.h
@@ -44,7 +44,7 @@ void disable_bootsplash(void);
// cdrom.c
extern u8 CDRom_locks[];
-extern struct cdemu_s CDEmu;
+extern struct eltorito_s CDEmu;
extern struct drive_s *cdemu_drive_gf;
struct disk_op_s;
int process_cdemu_op(struct disk_op_s *op);