This eliminates the limit on the number of available drives. It also allows for each driver to allocate additional custom fields. --- src/ata.c | 14 ++++++++++---- src/biosvar.h | 6 ++++-- src/block.c | 46 +++++++++++++--------------------------------- src/boot.c | 2 +- src/cdrom.c | 10 ++++++---- src/config.h | 4 +--- src/disk.h | 11 +++-------- src/floppy.c | 7 +++++-- 8 files changed, 43 insertions(+), 57 deletions(-)
diff --git a/src/ata.c b/src/ata.c index a27da56..f935e1f 100644 --- a/src/ata.c +++ b/src/ata.c @@ -775,9 +775,12 @@ init_drive_atapi(struct drive_s *dummy, u16 *buffer) return NULL;
// Success - setup as ATAPI. - struct drive_s *drive_g = allocDrive(); - if (! drive_g) + struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g)); + if (! drive_g) { + warn_noalloc(); return NULL; + } + memset(drive_g, 0, sizeof(*drive_g)); SET_GLOBAL(drive_g->cntl_id, dummy->cntl_id); extract_identify(drive_g, buffer); SET_GLOBAL(drive_g->type, DTYPE_ATAPI); @@ -821,9 +824,12 @@ init_drive_ata(struct drive_s *dummy, u16 *buffer) return NULL;
// Success - setup as ATA. - struct drive_s *drive_g = allocDrive(); - if (! drive_g) + struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g)); + if (! drive_g) { + warn_noalloc(); return NULL; + } + memset(drive_g, 0, sizeof(*drive_g)); SET_GLOBAL(drive_g->cntl_id, dummy->cntl_id); extract_identify(drive_g, buffer); SET_GLOBAL(drive_g->type, DTYPE_ATA); diff --git a/src/biosvar.h b/src/biosvar.h index d011966..c67503c 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -329,9 +329,11 @@ static inline u16 get_global_seg(void) { (var) = (val); \ } while (0) #if MODESEGMENT -#define ADJUST_GLOBAL_PTR(var) (var) +#define STORE_GLOBAL_PTR(var) (var) +#define RETRIEVE_GLOBAL_PTR(var) (var) #else -#define ADJUST_GLOBAL_PTR(var) ((typeof(var))((void*)var - BUILD_BIOS_ADDR)) +#define STORE_GLOBAL_PTR(var) ((typeof(var))((void*)var - BUILD_BIOS_ADDR)) +#define RETRIEVE_GLOBAL_PTR(var) ((typeof(var))((void*)var + BUILD_BIOS_ADDR)) #endif
diff --git a/src/block.c b/src/block.c index 3a9a68d..63aa368 100644 --- a/src/block.c +++ b/src/block.c @@ -16,30 +16,9 @@ struct drives_s Drives VAR16VISIBLE; struct drive_s * getDrive(u8 exttype, u8 extdriveoffset) { - // basic check : device has to be defined if (extdriveoffset >= ARRAY_SIZE(Drives.idmap[0])) return NULL; - - // Get the ata channel - u8 driveid = GET_GLOBAL(Drives.idmap[exttype][extdriveoffset]); - - // basic check : device has to be valid - if (driveid >= ARRAY_SIZE(Drives.drives)) - return NULL; - - return &Drives.drives[driveid]; -} - -struct drive_s * -allocDrive(void) -{ - int driveid = Drives.drivecount; - if (driveid >= ARRAY_SIZE(Drives.drives)) - return NULL; - Drives.drivecount++; - struct drive_s *drive_g = &Drives.drives[driveid]; - memset(drive_g, 0, sizeof(*drive_g)); - return drive_g; + return RETRIEVE_GLOBAL_PTR(GET_GLOBAL(Drives.idmap[exttype][extdriveoffset])); }
@@ -208,11 +187,12 @@ map_hd_drive(struct drive_s *drive_g) { // fill hdidmap u8 hdcount = GET_BDA(hdcount); - if (hdcount >= ARRAY_SIZE(Drives.idmap[0])) + if (hdcount >= ARRAY_SIZE(Drives.idmap[0])) { + warn_noalloc(); return; + } dprintf(3, "Mapping hd drive %p to %d\n", drive_g, hdcount); - int driveid = drive_g - Drives.drives; - SET_GLOBAL(Drives.idmap[EXTTYPE_HD][hdcount], driveid); + Drives.idmap[EXTTYPE_HD][hdcount] = STORE_GLOBAL_PTR(drive_g); SET_BDA(hdcount, hdcount + 1);
// Fill "fdpt" structure. @@ -221,22 +201,22 @@ map_hd_drive(struct drive_s *drive_g)
// Find spot to add a drive static void -add_ordered_drive(u8 *idmap, u8 *count, struct drive_s *drive_g) +add_ordered_drive(struct drive_s **idmap, u8 *count, struct drive_s *drive_g) { if (*count >= ARRAY_SIZE(Drives.idmap[0])) { warn_noalloc(); return; } - u8 *pos = &idmap[*count]; + struct drive_s **pos = &idmap[*count]; *count = *count + 1; if (CONFIG_THREADS) { // Add to idmap with assured drive order. - u8 *end = pos; + struct drive_s **end = pos; for (;;) { - u8 *prev = pos - 1; + struct drive_s **prev = pos - 1; if (prev < idmap) break; - struct drive_s *prevdrive = &Drives.drives[*prev]; + struct drive_s *prevdrive = *prev; if (prevdrive->type < drive_g->type || (prevdrive->type == drive_g->type && prevdrive->cntl_id < drive_g->cntl_id)) @@ -246,7 +226,7 @@ add_ordered_drive(u8 *idmap, u8 *count, struct drive_s *drive_g) if (pos != end) memmove(pos+1, pos, (void*)end-(void*)pos); } - *pos = drive_g - Drives.drives; + *pos = STORE_GLOBAL_PTR(drive_g); }
// Map a cd @@ -312,6 +292,7 @@ describe_drive(struct drive_s *drive_g) int process_op(struct disk_op_s *op) { + ASSERT16(); u8 type = GET_GLOBAL(op->drive_g->type); switch (type) { case DTYPE_FLOPPY: @@ -355,9 +336,9 @@ __send_disk_op(struct disk_op_s *op_far, u16 op_seg) int send_disk_op(struct disk_op_s *op) { + ASSERT16(); if (! CONFIG_DRIVES) return -1; - ASSERT16();
return stack_hop((u32)op, GET_SEG(SS), 0, __send_disk_op); } @@ -371,5 +352,4 @@ void drive_setup(void) { memset(&Drives, 0, sizeof(Drives)); - memset(&Drives.idmap, 0xff, sizeof(Drives.idmap)); } diff --git a/src/boot.c b/src/boot.c index 151b0d3..6b69dc2 100644 --- a/src/boot.c +++ b/src/boot.c @@ -321,7 +321,7 @@ boot_prep(void)
// Setup floppy boot order int override = IPL.bev[0].subchoice; - int tmp = Drives.idmap[EXTTYPE_FLOPPY][0]; + struct drive_s *tmp = Drives.idmap[EXTTYPE_FLOPPY][0]; Drives.idmap[EXTTYPE_FLOPPY][0] = Drives.idmap[EXTTYPE_FLOPPY][override]; Drives.idmap[EXTTYPE_FLOPPY][override] = tmp;
diff --git a/src/cdrom.c b/src/cdrom.c index 4e70729..06adefa 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -113,12 +113,14 @@ cdemu_setup(void) if (!CONFIG_CDROM_EMU) return;
- struct drive_s *drive_g = allocDrive(); - if (!drive_g) { + struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g)); + if (! drive_g) { + warn_noalloc(); cdemu_drive = NULL; return; } - cdemu_drive = ADJUST_GLOBAL_PTR(drive_g); + memset(drive_g, 0, sizeof(*drive_g)); + cdemu_drive = STORE_GLOBAL_PTR(drive_g); drive_g->type = DTYPE_CDEMU; drive_g->blksize = DISK_SECTOR_SIZE; drive_g->sectors = (u64)-1; @@ -327,7 +329,7 @@ cdrom_boot(int cdid) u8 media = buffer[0x21]; SET_EBDA2(ebda_seg, cdemu.media, media);
- SET_EBDA2(ebda_seg, cdemu.emulated_drive, ADJUST_GLOBAL_PTR(dop.drive_g)); + SET_EBDA2(ebda_seg, cdemu.emulated_drive, STORE_GLOBAL_PTR(dop.drive_g));
u16 boot_segment = *(u16*)&buffer[0x22]; if (!boot_segment) diff --git a/src/config.h b/src/config.h index c02d496..e359652 100644 --- a/src/config.h +++ b/src/config.h @@ -119,15 +119,13 @@ #define CONFIG_USE_SMM 1 // Maximum number of map entries in the e820 map #define CONFIG_MAX_E820 32 -// Space to reserve in f-segment for run-time built bios tables. +// Space to reserve in f-segment for dynamic allocations #define CONFIG_MAX_BIOSTABLE 2048 // Space to reserve in high-memory for tables #define CONFIG_MAX_HIGHTABLE (64*1024)
// Maximum number of ATA controllers to support #define CONFIG_MAX_ATA_INTERFACES 4 -// Maximum number of internal drives supported -#define CONFIG_MAX_DRIVES 8 // Largest supported externaly facing drive id #define CONFIG_MAX_EXTDRIVE 16
diff --git a/src/disk.h b/src/disk.h index ac5748e..635d511 100644 --- a/src/disk.h +++ b/src/disk.h @@ -173,7 +173,7 @@ struct chs_s { };
struct drive_s { - u8 type; // Detected type of drive (ata/atapi/none) + u8 type; // Driver type (DTYPE_*) u8 removable; // Removable device flag u16 blksize; // block size u32 cntl_id; @@ -205,14 +205,10 @@ struct drive_s { #define TRANSLATION_RECHS 3
struct drives_s { - // info on each internally handled drive - struct drive_s drives[CONFIG_MAX_DRIVES]; - u8 drivecount; - // - // map between bios floppy/hd/cd id and driveid index into drives[] + // map between bios floppy/hd/cd id and drive_s struct u8 floppycount; u8 cdcount; - u8 idmap[3][CONFIG_MAX_EXTDRIVE]; + struct drive_s *idmap[3][CONFIG_MAX_EXTDRIVE]; };
#define EXTTYPE_FLOPPY 0 @@ -230,7 +226,6 @@ struct drives_s { // block.c extern struct drives_s Drives; struct drive_s *getDrive(u8 exttype, u8 extdriveoffset); -struct drive_s *allocDrive(void); void setup_translation(struct drive_s *drive_g); void map_floppy_drive(struct drive_s *drive_g); void map_hd_drive(struct drive_s *drive_g); diff --git a/src/floppy.c b/src/floppy.c index dba3e00..d2e689c 100644 --- a/src/floppy.c +++ b/src/floppy.c @@ -96,9 +96,12 @@ addFloppy(int floppyid, int ftype, int driver) return NULL; }
- struct drive_s *drive_g = allocDrive(); - if (!drive_g) + struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g)); + if (!drive_g) { + warn_noalloc(); return NULL; + } + memset(drive_g, 0, sizeof(*drive_g)); drive_g->cntl_id = floppyid; drive_g->type = driver; drive_g->blksize = DISK_SECTOR_SIZE;