[SeaBIOS] [PATCH 1/2] cdemu: store internal cdemu fields in standard "el-torito" spec format.

Kevin O'Connor kevin at koconnor.net
Sat May 31 02:24:13 CEST 2014


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 at koconnor.net>
---
 src/block.h    | 15 ------------
 src/boot.c     |  2 +-
 src/cdrom.c    | 72 ++++++++++++++++++++--------------------------------------
 src/disk.c     | 15 ++++++------
 src/std/disk.h |  8 +++----
 src/util.h     |  2 +-
 6 files changed, 38 insertions(+), 76 deletions(-)

diff --git a/src/block.h b/src/block.h
index c870e13..945e6fe 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 133e206..9be8b2a 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 ff419c0..f0d8a1a 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 7e42103..635d7b9 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 b2576d9..6397108 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 b54271b..74b58f4 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);
-- 
1.9.3




More information about the SeaBIOS mailing list