diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2008-12-28 23:18:57 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2008-12-28 23:18:57 -0500 |
commit | 609da236ef0d7f81806bc35ae5f67bf7a0e23df1 (patch) | |
tree | bc4daf25a68c1b1f4613c4d52610d2146eb6289c | |
parent | e79163695a2518ad2e87cb75b80c9e7deb2972b1 (diff) | |
download | seabios-hppa-609da236ef0d7f81806bc35ae5f67bf7a0e23df1.zip seabios-hppa-609da236ef0d7f81806bc35ae5f67bf7a0e23df1.tar.gz seabios-hppa-609da236ef0d7f81806bc35ae5f67bf7a0e23df1.tar.bz2 |
Move most of ATA and CDEMU from ebda to global variables.
The dpte, cdrom locks, and disk sector count remain in the ebda.
Also, enhance SET_GLOBAL macro to avoid unused variable warnings.
-rw-r--r-- | src/ata.c | 143 | ||||
-rw-r--r-- | src/biosvar.h | 118 | ||||
-rw-r--r-- | src/boot.c | 4 | ||||
-rw-r--r-- | src/cdrom.c | 112 | ||||
-rw-r--r-- | src/disk.c | 96 | ||||
-rw-r--r-- | src/disk.h | 74 |
6 files changed, 283 insertions, 264 deletions
@@ -15,6 +15,7 @@ #include "pci.h" // pci_find_class #include "pci_ids.h" // PCI_CLASS_STORAGE_OTHER #include "pci_regs.h" // PCI_INTERRUPT_LINE +#include "disk.h" // struct ata_s #define TIMEOUT 0 #define BSY 1 @@ -28,6 +29,8 @@ #define IDE_TIMEOUT 32000u //32 seconds max for IDE ops +struct ata_s ATA VAR16; + /**************************************************************** * Helper functions @@ -91,8 +94,8 @@ ata_reset(int driveid) { u8 channel = driveid / 2; u8 slave = driveid % 2; - u16 iobase1 = GET_EBDA(ata.channels[channel].iobase1); - u16 iobase2 = GET_EBDA(ata.channels[channel].iobase2); + u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1); + u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2); // Reset @@ -115,7 +118,7 @@ ata_reset(int driveid) // For predetermined ATA drives - wait for ready. if (sc==0x01 && sn==0x01) { - u8 type=GET_EBDA(ata.devices[driveid].type); + u8 type=GET_GLOBAL(ATA.devices[driveid].type); if (type == ATA_TYPE_ATA) await_ide(NOT_BSY_RDY, iobase1, IDE_TIMEOUT); } @@ -160,8 +163,8 @@ static int send_cmd(int driveid, struct ata_pio_command *cmd) { u8 channel = driveid / 2; - u16 iobase1 = GET_EBDA(ata.channels[channel].iobase1); - u16 iobase2 = GET_EBDA(ata.channels[channel].iobase2); + u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1); + u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2); int status = inb(iobase1 + ATA_CB_STAT); if (status & ATA_CB_STAT_BSY) @@ -244,12 +247,12 @@ ata_transfer(int driveid, int iswrite, int count, int blocksize , skipfirst, skiplast, far_buffer); // Reset count of transferred data - SET_EBDA(ata.trsfsectors, 0); + SET_EBDA(sector_count, 0); u8 channel = driveid / 2; - u16 iobase1 = GET_EBDA(ata.channels[channel].iobase1); - u16 iobase2 = GET_EBDA(ata.channels[channel].iobase2); - u8 mode = GET_EBDA(ata.devices[driveid].mode); + u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1); + u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2); + u8 mode = GET_GLOBAL(ATA.devices[driveid].mode); int current = 0; int status; for (;;) { @@ -287,7 +290,7 @@ ata_transfer(int driveid, int iswrite, int count, int blocksize return status; current++; - SET_EBDA(ata.trsfsectors, current); + SET_EBDA(sector_count, current); if (current == count) break; status &= (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ @@ -335,10 +338,10 @@ ata_transfer_emu(const struct ata_op_s *op, int before, int after) int ret = ata_transfer(op->driveid, 0, op->count, CDROM_SECTOR_SIZE , before*512, after*512, op->far_buffer); if (ret) { - SET_EBDA(ata.trsfsectors, 0); + SET_EBDA(sector_count, 0); return ret; } - SET_EBDA(ata.trsfsectors, vcount); + SET_EBDA(sector_count, vcount); return 0; } @@ -407,8 +410,8 @@ send_atapi_cmd(int driveid, u8 *cmdbuf, u8 cmdlen, u16 blocksize) { u8 channel = driveid / 2; u8 slave = driveid % 2; - u16 iobase1 = GET_EBDA(ata.channels[channel].iobase1); - u16 iobase2 = GET_EBDA(ata.channels[channel].iobase2); + u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1); + u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2); struct ata_pio_command cmd; cmd.sector_count = 0; @@ -556,11 +559,11 @@ get_ata_version(u8 *buffer) static void init_drive_atapi(int driveid) { - SET_EBDA(ata.devices[driveid].type, ATA_TYPE_ATAPI); + SET_GLOBAL(ATA.devices[driveid].type, ATA_TYPE_ATAPI); // Temporary values to do the transfer - SET_EBDA(ata.devices[driveid].device,ATA_DEVICE_CDROM); - SET_EBDA(ata.devices[driveid].mode, ATA_MODE_PIO16); + SET_GLOBAL(ATA.devices[driveid].device,ATA_DEVICE_CDROM); + SET_GLOBAL(ATA.devices[driveid].mode, ATA_MODE_PIO16); // Now we send a IDENTIFY command to ATAPI device u8 buffer[0x0200]; @@ -576,19 +579,19 @@ init_drive_atapi(int driveid) u8 mode = buffer[96] ? ATA_MODE_PIO32 : ATA_MODE_PIO16; u16 blksize = CDROM_SECTOR_SIZE; - SET_EBDA(ata.devices[driveid].device, type); - SET_EBDA(ata.devices[driveid].removable, removable); - SET_EBDA(ata.devices[driveid].mode, mode); - SET_EBDA(ata.devices[driveid].blksize, blksize); + SET_GLOBAL(ATA.devices[driveid].device, type); + SET_GLOBAL(ATA.devices[driveid].removable, removable); + SET_GLOBAL(ATA.devices[driveid].mode, mode); + SET_GLOBAL(ATA.devices[driveid].blksize, blksize); // fill cdidmap - u8 cdcount = GET_EBDA(ata.cdcount); - SET_EBDA(ata.idmap[1][cdcount], driveid); - SET_EBDA(ata.cdcount, ++cdcount); + u8 cdcount = GET_GLOBAL(ATA.cdcount); + SET_GLOBAL(ATA.idmap[1][cdcount], driveid); + SET_GLOBAL(ATA.cdcount, ++cdcount); report_model(driveid, buffer); u8 version = get_ata_version(buffer); - if (GET_EBDA(ata.devices[driveid].device)==ATA_DEVICE_CDROM) + if (GET_GLOBAL(ATA.devices[driveid].device)==ATA_DEVICE_CDROM) printf(" ATAPI-%d CD-Rom/DVD-Rom\n", version); else printf(" ATAPI-%d Device\n", version); @@ -600,15 +603,15 @@ fill_fdpt(int driveid) if (driveid > 1) return; - struct extended_bios_data_area_s *ebda = get_ebda_ptr(); - u16 nlc = ebda->ata.devices[driveid].lchs.cylinders; - u16 nlh = ebda->ata.devices[driveid].lchs.heads; - u16 nlspt = ebda->ata.devices[driveid].lchs.spt; + u16 nlc = GET_GLOBAL(ATA.devices[driveid].lchs.cylinders); + u16 nlh = GET_GLOBAL(ATA.devices[driveid].lchs.heads); + u16 nlspt = GET_GLOBAL(ATA.devices[driveid].lchs.spt); - u16 npc = ebda->ata.devices[driveid].pchs.cylinders; - u16 nph = ebda->ata.devices[driveid].pchs.heads; - u16 npspt = ebda->ata.devices[driveid].pchs.spt; + u16 npc = GET_GLOBAL(ATA.devices[driveid].pchs.cylinders); + u16 nph = GET_GLOBAL(ATA.devices[driveid].pchs.heads); + u16 npspt = GET_GLOBAL(ATA.devices[driveid].pchs.spt); + struct extended_bios_data_area_s *ebda = get_ebda_ptr(); ebda->fdpt[driveid].precompensation = 0xffff; ebda->fdpt[driveid].drive_control_byte = 0xc0 | ((nph > 8) << 3); ebda->fdpt[driveid].landing_zone = npc; @@ -646,9 +649,9 @@ get_translation(int driveid) } // On COREBOOT, use a heuristic to determine translation type. - u16 heads = GET_EBDA(ata.devices[driveid].pchs.heads); - u16 cylinders = GET_EBDA(ata.devices[driveid].pchs.cylinders); - u16 spt = GET_EBDA(ata.devices[driveid].pchs.spt); + u16 heads = GET_GLOBAL(ATA.devices[driveid].pchs.heads); + u16 cylinders = GET_GLOBAL(ATA.devices[driveid].pchs.cylinders); + u16 spt = GET_GLOBAL(ATA.devices[driveid].pchs.spt); if (cylinders <= 1024 && heads <= 16 && spt <= 63) return ATA_TRANSLATION_NONE; @@ -661,14 +664,14 @@ static void setup_translation(int driveid) { u8 translation = get_translation(driveid); - SET_EBDA(ata.devices[driveid].translation, translation); + SET_GLOBAL(ATA.devices[driveid].translation, translation); u8 channel = driveid / 2; u8 slave = driveid % 2; - u16 heads = GET_EBDA(ata.devices[driveid].pchs.heads); - u16 cylinders = GET_EBDA(ata.devices[driveid].pchs.cylinders); - u16 spt = GET_EBDA(ata.devices[driveid].pchs.spt); - u64 sectors = GET_EBDA(ata.devices[driveid].sectors); + u16 heads = GET_GLOBAL(ATA.devices[driveid].pchs.heads); + u16 cylinders = GET_GLOBAL(ATA.devices[driveid].pchs.cylinders); + u16 spt = GET_GLOBAL(ATA.devices[driveid].pchs.spt); + u64 sectors = GET_GLOBAL(ATA.devices[driveid].sectors); dprintf(1, "ata%d-%d: PCHS=%u/%d/%d translation=" , channel, slave, cylinders, heads, spt); @@ -726,19 +729,19 @@ setup_translation(int driveid) cylinders = 1024; dprintf(1, " LCHS=%d/%d/%d\n", cylinders, heads, spt); - SET_EBDA(ata.devices[driveid].lchs.heads, heads); - SET_EBDA(ata.devices[driveid].lchs.cylinders, cylinders); - SET_EBDA(ata.devices[driveid].lchs.spt, spt); + SET_GLOBAL(ATA.devices[driveid].lchs.heads, heads); + SET_GLOBAL(ATA.devices[driveid].lchs.cylinders, cylinders); + SET_GLOBAL(ATA.devices[driveid].lchs.spt, spt); } static void init_drive_ata(int driveid) { - SET_EBDA(ata.devices[driveid].type, ATA_TYPE_ATA); + SET_GLOBAL(ATA.devices[driveid].type, ATA_TYPE_ATA); // Temporary values to do the transfer - SET_EBDA(ata.devices[driveid].device, ATA_DEVICE_HD); - SET_EBDA(ata.devices[driveid].mode, ATA_MODE_PIO16); + SET_GLOBAL(ATA.devices[driveid].device, ATA_DEVICE_HD); + SET_GLOBAL(ATA.devices[driveid].mode, ATA_MODE_PIO16); // Now we send a IDENTIFY command to ATA device u8 buffer[0x0200]; @@ -763,28 +766,28 @@ init_drive_ata(int driveid) else sectors = *(u32*)&buffer[60*2]; // word 60 and word 61 - SET_EBDA(ata.devices[driveid].device, ATA_DEVICE_HD); - SET_EBDA(ata.devices[driveid].removable, removable); - SET_EBDA(ata.devices[driveid].mode, mode); - SET_EBDA(ata.devices[driveid].blksize, blksize); - SET_EBDA(ata.devices[driveid].pchs.heads, heads); - SET_EBDA(ata.devices[driveid].pchs.cylinders, cylinders); - SET_EBDA(ata.devices[driveid].pchs.spt, spt); - SET_EBDA(ata.devices[driveid].sectors, sectors); + SET_GLOBAL(ATA.devices[driveid].device, ATA_DEVICE_HD); + SET_GLOBAL(ATA.devices[driveid].removable, removable); + SET_GLOBAL(ATA.devices[driveid].mode, mode); + SET_GLOBAL(ATA.devices[driveid].blksize, blksize); + SET_GLOBAL(ATA.devices[driveid].pchs.heads, heads); + SET_GLOBAL(ATA.devices[driveid].pchs.cylinders, cylinders); + SET_GLOBAL(ATA.devices[driveid].pchs.spt, spt); + SET_GLOBAL(ATA.devices[driveid].sectors, sectors); // Setup disk geometry translation. setup_translation(driveid); // fill hdidmap - u8 hdcount = GET_EBDA(ata.hdcount); - SET_EBDA(ata.idmap[0][hdcount], driveid); - SET_EBDA(ata.hdcount, ++hdcount); + u8 hdcount = GET_GLOBAL(ATA.hdcount); + SET_GLOBAL(ATA.idmap[0][hdcount], driveid); + SET_GLOBAL(ATA.hdcount, ++hdcount); // Fill "fdpt" structure. fill_fdpt(driveid); // Report drive info to user. - u64 sizeinmb = GET_EBDA(ata.devices[driveid].sectors) >> 11; + u64 sizeinmb = GET_GLOBAL(ATA.devices[driveid].sectors) >> 11; report_model(driveid, buffer); u8 version = get_ata_version(buffer); if (sizeinmb < (1 << 16)) @@ -797,7 +800,7 @@ init_drive_ata(int driveid) static void init_drive_unknown(int driveid) { - SET_EBDA(ata.devices[driveid].type, ATA_TYPE_UNKNOWN); + SET_GLOBAL(ATA.devices[driveid].type, ATA_TYPE_UNKNOWN); u8 channel = driveid / 2; u8 slave = driveid % 2; @@ -813,8 +816,8 @@ ata_detect() u8 channel = driveid / 2; u8 slave = driveid % 2; - u16 iobase1 = GET_EBDA(ata.channels[channel].iobase1); - u16 iobase2 = GET_EBDA(ata.channels[channel].iobase2); + u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1); + u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2); if (!iobase1) break; @@ -878,8 +881,8 @@ ata_init() // hdidmap and cdidmap init. u8 device; for (device=0; device < CONFIG_MAX_ATA_DEVICES; device++) { - SET_EBDA(ata.idmap[0][device], CONFIG_MAX_ATA_DEVICES); - SET_EBDA(ata.idmap[1][device], CONFIG_MAX_ATA_DEVICES); + SET_GLOBAL(ATA.idmap[0][device], CONFIG_MAX_ATA_DEVICES); + SET_GLOBAL(ATA.idmap[1][device], CONFIG_MAX_ATA_DEVICES); } // Scan PCI bus for ATA adapters @@ -890,8 +893,8 @@ ata_init() continue; u8 irq = pci_config_readb(bdf, PCI_INTERRUPT_LINE); - SET_EBDA(ata.channels[count].irq, irq); - SET_EBDA(ata.channels[count].pci_bdf, bdf); + SET_GLOBAL(ATA.channels[count].irq, irq); + SET_GLOBAL(ATA.channels[count].pci_bdf, bdf); u8 prog_if = pci_config_readb(bdf, PCI_CLASS_PROG); u32 port1, port2; @@ -903,8 +906,8 @@ ata_init() port1 = 0x1f0; port2 = 0x3f0; } - SET_EBDA(ata.channels[count].iobase1, port1); - SET_EBDA(ata.channels[count].iobase2, port2); + SET_GLOBAL(ATA.channels[count].iobase1, port1); + SET_GLOBAL(ATA.channels[count].iobase2, port2); dprintf(1, "ATA controller %d at %x/%x (dev %x prog_if %x)\n" , count, port1, port2, bdf, prog_if); count++; @@ -918,8 +921,8 @@ ata_init() } dprintf(1, "ATA controller %d at %x/%x (dev %x prog_if %x)\n" , count, port1, port2, bdf, prog_if); - SET_EBDA(ata.channels[count].iobase1, port1); - SET_EBDA(ata.channels[count].iobase2, port2); + SET_GLOBAL(ATA.channels[count].iobase1, port1); + SET_GLOBAL(ATA.channels[count].iobase2, port2); count++; } } @@ -935,7 +938,7 @@ hard_drive_setup() ata_detect(); // Store the device count - SET_BDA(disk_count, GET_EBDA(ata.hdcount)); + SET_BDA(disk_count, GET_GLOBAL(ATA.hdcount)); SET_BDA(disk_control_byte, 0xc0); diff --git a/src/biosvar.h b/src/biosvar.h index b106bb0..dc70802 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -129,89 +129,6 @@ struct bios_data_area_s { /**************************************************************** - * Hard drive info - ****************************************************************/ - -struct chs_s { - u16 heads; // # heads - u16 cylinders; // # cylinders - u16 spt; // # sectors / track -}; - -// DPTE definition -struct dpte_s { - u16 iobase1; - u16 iobase2; - u8 prefix; - u8 unused; - u8 irq; - u8 blkcount; - u8 dma; - u8 pio; - u16 options; - u16 reserved; - u8 revision; - u8 checksum; -}; - -struct ata_channel_s { - u16 iobase1; // IO Base 1 - u16 iobase2; // IO Base 2 - u16 pci_bdf; - u8 irq; // IRQ -}; - -struct ata_device_s { - u8 type; // Detected type of ata (ata/atapi/none/unknown) - u8 device; // Detected type of attached devices (hd/cd/none) - u8 removable; // Removable device flag - u8 lock; // Locks for removable devices - u8 mode; // transfer mode : PIO 16/32 bits - IRQ - ISADMA - PCIDMA - u16 blksize; // block size - - u8 translation; // type of translation - struct chs_s lchs; // Logical CHS - struct chs_s pchs; // Physical CHS - - u64 sectors; // Total sectors count -}; - -struct ata_s { - // ATA channels info - struct ata_channel_s channels[CONFIG_MAX_ATA_INTERFACES]; - - // ATA devices info - struct ata_device_s devices[CONFIG_MAX_ATA_DEVICES]; - // - // map between bios hd/cd id and ata channels - u8 hdcount, cdcount; - u8 idmap[2][CONFIG_MAX_ATA_DEVICES]; - - // Buffer for DPTE table - struct dpte_s dpte; - - // Count of transferred sectors and bytes - u16 trsfsectors; -}; - -// ElTorito Device Emulation data -struct cdemu_s { - u8 active; - u8 media; - u8 emulated_drive; - u8 controller_index; - u16 device_spec; - u32 ilba; - u16 buffer_segment; - u16 load_segment; - u16 sector_count; - - // Virtual device - struct chs_s vdevice; -}; - - -/**************************************************************** * Initial Program Load (IPL) ****************************************************************/ @@ -240,6 +157,22 @@ struct ipl_s { * Extended Bios Data Area (EBDA) ****************************************************************/ +// DPTE definition +struct dpte_s { + u16 iobase1; + u16 iobase2; + u8 prefix; + u8 unused; + u8 irq; + u8 blkcount; + u8 dma; + u8 pio; + u16 options; + u16 reserved; + u8 revision; + u8 checksum; +}; + struct fdpt_s { u16 cylinders; u8 heads; @@ -274,11 +207,16 @@ struct extended_bios_data_area_s { // 0x121 - Begin custom storage. u8 ps2ctr; - // ATA Driver data - struct ata_s ata; + u8 cdemu_active; - // El Torito Emulation data - struct cdemu_s cdemu; + // Count of transferred sectors and bytes to/from disk + u16 sector_count; + + // Buffer for disk DPTE table + struct dpte_s dpte; + + // Locks for removable devices + u8 cdrom_locks[CONFIG_MAX_ATA_DEVICES]; // Initial program load struct ipl_s ipl; @@ -310,8 +248,10 @@ get_ebda_ptr() GET_VAR(CS, (var)) #if MODE16 extern void __force_link_error__set_global_only_in_32bit(); -#define SET_GLOBAL(var, val) \ - __force_link_error__set_global_only_in_32bit() +#define SET_GLOBAL(var, val) do { \ + (void)(val); \ + __force_link_error__set_global_only_in_32bit(); \ + } while (0) #else #define SET_GLOBAL(var, val) \ do { (var) = (val); } while (0) @@ -151,8 +151,8 @@ try_boot(u16 seq_nr) return; } - bootdrv = GET_EBDA(cdemu.emulated_drive); - bootseg = GET_EBDA(cdemu.load_segment); + bootdrv = GET_GLOBAL(CDEMU.emulated_drive); + bootseg = GET_GLOBAL(CDEMU.load_segment); /* Canonicalize bootseg:bootip */ bootip = (bootseg & 0x0fff) << 4; bootseg &= 0xf000; diff --git a/src/cdrom.c b/src/cdrom.c index 65b5bbe..f955f18 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -11,6 +11,8 @@ #include "bregs.h" // struct bregs #include "biosvar.h" // GET_EBDA +struct cdemu_s CDEMU VAR16; + /**************************************************************** * CDROM functions @@ -27,13 +29,13 @@ cdrom_1315(struct bregs *regs, u8 device) static void cdrom_134500(struct bregs *regs, u8 device) { - u8 locks = GET_EBDA(ata.devices[device].lock); + u8 locks = GET_EBDA(cdrom_locks[device]); if (locks == 0xff) { regs->al = 1; disk_ret(regs, DISK_RET_ETOOMANYLOCKS); return; } - SET_EBDA(ata.devices[device].lock, locks + 1); + SET_EBDA(cdrom_locks[device], locks + 1); regs->al = 1; disk_ret(regs, DISK_RET_SUCCESS); } @@ -42,14 +44,14 @@ cdrom_134500(struct bregs *regs, u8 device) static void cdrom_134501(struct bregs *regs, u8 device) { - u8 locks = GET_EBDA(ata.devices[device].lock); + u8 locks = GET_EBDA(cdrom_locks[device]); if (locks == 0x00) { regs->al = 0; disk_ret(regs, DISK_RET_ENOTLOCKED); return; } locks--; - SET_EBDA(ata.devices[device].lock, locks); + SET_EBDA(cdrom_locks[device], locks); regs->al = (locks ? 1 : 0); disk_ret(regs, DISK_RET_SUCCESS); } @@ -58,7 +60,7 @@ cdrom_134501(struct bregs *regs, u8 device) static void cdrom_134502(struct bregs *regs, u8 device) { - u8 locks = GET_EBDA(ata.devices[device].lock); + u8 locks = GET_EBDA(cdrom_locks[device]); regs->al = (locks ? 1 : 0); disk_ret(regs, DISK_RET_SUCCESS); } @@ -85,7 +87,7 @@ cdrom_1345(struct bregs *regs, u8 device) static void cdrom_1346(struct bregs *regs, u8 device) { - u8 locks = GET_EBDA(ata.devices[device].lock); + u8 locks = GET_EBDA(cdrom_locks[device]); if (locks != 0) { disk_ret(regs, DISK_RET_ELOCKED); return; @@ -183,7 +185,7 @@ cdrom_13(struct bregs *regs, u8 device) __always_inline int cdrom_read_emu(u16 biosid, u32 vlba, u32 count, void *far_buffer) { - u32 ilba = GET_EBDA(cdemu.ilba); + u32 ilba = GET_GLOBAL(CDEMU.ilba); return cdrom_read_512(biosid, ilba * 4 + vlba, count, far_buffer); } @@ -191,9 +193,9 @@ cdrom_read_emu(u16 biosid, u32 vlba, u32 count, void *far_buffer) static void cdemu_1308(struct bregs *regs, u8 device) { - u16 nlc = GET_EBDA(cdemu.vdevice.cylinders) - 1; - u16 nlh = GET_EBDA(cdemu.vdevice.heads) - 1; - u16 nlspt = GET_EBDA(cdemu.vdevice.spt); + u16 nlc = GET_GLOBAL(CDEMU.vdevice.cylinders) - 1; + u16 nlh = GET_GLOBAL(CDEMU.vdevice.heads) - 1; + u16 nlspt = GET_GLOBAL(CDEMU.vdevice.spt); regs->al = 0x00; regs->bl = 0x00; @@ -203,7 +205,7 @@ cdemu_1308(struct bregs *regs, u8 device) // FIXME ElTorito Various. should send the real count of drives 1 or 2 // FIXME ElTorito Harddisk. should send the HD count regs->dl = 0x02; - u8 media = GET_EBDA(cdemu.media); + u8 media = GET_GLOBAL(CDEMU.media); if (media <= 3) regs->bl = media * 2; @@ -218,8 +220,8 @@ cdemu_13(struct bregs *regs) { //debug_stub(regs); - u8 device = GET_EBDA(cdemu.controller_index) * 2; - device += GET_EBDA(cdemu.device_spec); + u8 device = GET_GLOBAL(CDEMU.controller_index) * 2; + device += GET_GLOBAL(CDEMU.device_spec); switch (regs->ah) { // These functions are the same as for hard disks @@ -274,22 +276,22 @@ cdemu_134b(struct bregs *regs) { // FIXME ElTorito Hardcoded SET_INT13ET(regs, size, 0x13); - SET_INT13ET(regs, media, GET_EBDA(cdemu.media)); - SET_INT13ET(regs, emulated_drive, GET_EBDA(cdemu.emulated_drive)); - SET_INT13ET(regs, controller_index, GET_EBDA(cdemu.controller_index)); - SET_INT13ET(regs, ilba, GET_EBDA(cdemu.ilba)); - SET_INT13ET(regs, device_spec, GET_EBDA(cdemu.device_spec)); - SET_INT13ET(regs, buffer_segment, GET_EBDA(cdemu.buffer_segment)); - SET_INT13ET(regs, load_segment, GET_EBDA(cdemu.load_segment)); - SET_INT13ET(regs, sector_count, GET_EBDA(cdemu.sector_count)); - SET_INT13ET(regs, cylinders, GET_EBDA(cdemu.vdevice.cylinders)); - SET_INT13ET(regs, sectors, GET_EBDA(cdemu.vdevice.spt)); - SET_INT13ET(regs, heads, GET_EBDA(cdemu.vdevice.heads)); + SET_INT13ET(regs, media, GET_GLOBAL(CDEMU.media)); + SET_INT13ET(regs, emulated_drive, GET_GLOBAL(CDEMU.emulated_drive)); + SET_INT13ET(regs, controller_index, GET_GLOBAL(CDEMU.controller_index)); + SET_INT13ET(regs, ilba, GET_GLOBAL(CDEMU.ilba)); + SET_INT13ET(regs, device_spec, GET_GLOBAL(CDEMU.device_spec)); + SET_INT13ET(regs, buffer_segment, GET_GLOBAL(CDEMU.buffer_segment)); + SET_INT13ET(regs, load_segment, GET_GLOBAL(CDEMU.load_segment)); + SET_INT13ET(regs, sector_count, GET_GLOBAL(CDEMU.sector_count)); + SET_INT13ET(regs, cylinders, GET_GLOBAL(CDEMU.vdevice.cylinders)); + SET_INT13ET(regs, sectors, GET_GLOBAL(CDEMU.vdevice.spt)); + SET_INT13ET(regs, heads, GET_GLOBAL(CDEMU.vdevice.heads)); // If we have to terminate emulation if (regs->al == 0x00) { // FIXME ElTorito Various. Should be handled accordingly to spec - SET_EBDA(cdemu.active, 0x00); // bye bye + SET_EBDA(cdemu_active, 0x00); // bye bye } disk_ret(regs, DISK_RET_SUCCESS); @@ -323,7 +325,7 @@ atapi_get_sense(u16 device, u8 *asc, u8 *ascq) static int atapi_is_ready(u16 device) { - if (GET_EBDA(ata.devices[device].type) != ATA_TYPE_ATAPI) { + if (GET_GLOBAL(ATA.devices[device].type) != ATA_TYPE_ATAPI) { printf("not implemented for non-ATAPI device\n"); return -1; } @@ -378,7 +380,7 @@ atapi_is_ready(u16 device) printf("Unsupported sector size %u\n", block_len); return -1; } - SET_EBDA(ata.devices[device].blksize, block_len); + SET_GLOBAL(ATA.devices[device].blksize, block_len); u32 sectors = (u32) buf[0] << 24 | (u32) buf[1] << 16 @@ -388,9 +390,9 @@ atapi_is_ready(u16 device) dprintf(6, "sectors=%u\n", sectors); if (block_len == 2048) sectors <<= 2; /* # of sectors in 512-byte "soft" sector */ - if (sectors != GET_EBDA(ata.devices[device].sectors)) + if (sectors != GET_GLOBAL(ATA.devices[device].sectors)) printf("%dMB medium detected\n", sectors>>(20-9)); - SET_EBDA(ata.devices[device].sectors, sectors); + SET_GLOBAL(ATA.devices[device].sectors, sectors); return 0; } @@ -400,10 +402,10 @@ atapi_is_cdrom(u8 device) if (device >= CONFIG_MAX_ATA_DEVICES) return 0; - if (GET_EBDA(ata.devices[device].type) != ATA_TYPE_ATAPI) + if (GET_GLOBAL(ATA.devices[device].type) != ATA_TYPE_ATAPI) return 0; - if (GET_EBDA(ata.devices[device].device) != ATA_DEVICE_CDROM) + if (GET_GLOBAL(ATA.devices[device].device) != ATA_DEVICE_CDROM) return 0; return 1; @@ -477,22 +479,22 @@ cdrom_boot() return 11; // Bootable u8 media = buffer[0x21]; - SET_EBDA(cdemu.media, media); + SET_GLOBAL(CDEMU.media, media); - SET_EBDA(cdemu.controller_index, device/2); - SET_EBDA(cdemu.device_spec, device%2); + SET_GLOBAL(CDEMU.controller_index, device/2); + SET_GLOBAL(CDEMU.device_spec, device%2); u16 boot_segment = *(u16*)&buffer[0x22]; if (!boot_segment) boot_segment = 0x07C0; - SET_EBDA(cdemu.load_segment, boot_segment); - SET_EBDA(cdemu.buffer_segment, 0x0000); + SET_GLOBAL(CDEMU.load_segment, boot_segment); + SET_GLOBAL(CDEMU.buffer_segment, 0x0000); u16 nbsectors = *(u16*)&buffer[0x26]; - SET_EBDA(cdemu.sector_count, nbsectors); + SET_GLOBAL(CDEMU.sector_count, nbsectors); lba = *(u32*)&buffer[0x28]; - SET_EBDA(cdemu.ilba, lba); + SET_GLOBAL(CDEMU.ilba, lba); // And we read the image in memory ret = cdrom_read_emu(device, 0, nbsectors, MAKE_FARPTR(boot_segment, 0)); @@ -504,7 +506,7 @@ cdrom_boot() // FIXME ElTorito Hardcoded. cdrom is hardcoded as device 0xE0. // Win2000 cd boot needs to know it booted from cd - SET_EBDA(cdemu.emulated_drive, 0xE0); + SET_GLOBAL(CDEMU.emulated_drive, 0xE0); return 0; } @@ -517,44 +519,44 @@ cdrom_boot() // number of devices if (media < 4) { // Floppy emulation - SET_EBDA(cdemu.emulated_drive, 0x00); + SET_GLOBAL(CDEMU.emulated_drive, 0x00); SETBITS_BDA(equipment_list_flags, 0x41); } else { // Harddrive emulation - SET_EBDA(cdemu.emulated_drive, 0x80); - SET_EBDA(ata.hdcount, GET_EBDA(ata.hdcount) + 1); + SET_GLOBAL(CDEMU.emulated_drive, 0x80); + SET_GLOBAL(ATA.hdcount, GET_GLOBAL(ATA.hdcount) + 1); } // Remember the media type switch (media) { case 0x01: // 1.2M floppy - SET_EBDA(cdemu.vdevice.spt, 15); - SET_EBDA(cdemu.vdevice.cylinders, 80); - SET_EBDA(cdemu.vdevice.heads, 2); + SET_GLOBAL(CDEMU.vdevice.spt, 15); + SET_GLOBAL(CDEMU.vdevice.cylinders, 80); + SET_GLOBAL(CDEMU.vdevice.heads, 2); break; case 0x02: // 1.44M floppy - SET_EBDA(cdemu.vdevice.spt, 18); - SET_EBDA(cdemu.vdevice.cylinders, 80); - SET_EBDA(cdemu.vdevice.heads, 2); + SET_GLOBAL(CDEMU.vdevice.spt, 18); + SET_GLOBAL(CDEMU.vdevice.cylinders, 80); + SET_GLOBAL(CDEMU.vdevice.heads, 2); break; case 0x03: // 2.88M floppy - SET_EBDA(cdemu.vdevice.spt, 36); - SET_EBDA(cdemu.vdevice.cylinders, 80); - SET_EBDA(cdemu.vdevice.heads, 2); + SET_GLOBAL(CDEMU.vdevice.spt, 36); + SET_GLOBAL(CDEMU.vdevice.cylinders, 80); + SET_GLOBAL(CDEMU.vdevice.heads, 2); break; case 0x04: { // Harddrive u16 spt = GET_FARVAR(boot_segment,*(u8*)(446+6)); u16 cyl = (spt << 2) + GET_FARVAR(boot_segment,*(u8*)(446+7)) + 1; u16 heads = GET_FARVAR(boot_segment,*(u8*)(446+5)) + 1; - SET_EBDA(cdemu.vdevice.spt, spt & 0x3f); - SET_EBDA(cdemu.vdevice.cylinders, cyl); - SET_EBDA(cdemu.vdevice.heads, heads); + SET_GLOBAL(CDEMU.vdevice.spt, spt & 0x3f); + SET_GLOBAL(CDEMU.vdevice.cylinders, cyl); + SET_GLOBAL(CDEMU.vdevice.heads, heads); break; } } // everything is ok, so from now on, the emulation is active - SET_EBDA(cdemu.active, 0x01); + SET_EBDA(cdemu_active, 0x01); dprintf(6, "cdemu media=%d\n", media); return 0; @@ -42,17 +42,17 @@ __disk_stub(const char *fname, int lineno, struct bregs *regs) static void basic_access(struct bregs *regs, u8 device, u16 command) { - u8 type = GET_EBDA(ata.devices[device].type); + u8 type = GET_GLOBAL(ATA.devices[device].type); u16 nlc, nlh, nlspt; if (type == ATA_TYPE_ATA) { - nlc = GET_EBDA(ata.devices[device].lchs.cylinders); - nlh = GET_EBDA(ata.devices[device].lchs.heads); - nlspt = GET_EBDA(ata.devices[device].lchs.spt); + nlc = GET_GLOBAL(ATA.devices[device].lchs.cylinders); + nlh = GET_GLOBAL(ATA.devices[device].lchs.heads); + nlspt = GET_GLOBAL(ATA.devices[device].lchs.spt); } else { // Must be cd emulation. - nlc = GET_EBDA(cdemu.vdevice.cylinders); - nlh = GET_EBDA(cdemu.vdevice.heads); - nlspt = GET_EBDA(cdemu.vdevice.spt); + nlc = GET_GLOBAL(CDEMU.vdevice.cylinders); + nlh = GET_GLOBAL(CDEMU.vdevice.heads); + nlspt = GET_GLOBAL(CDEMU.vdevice.spt); } u16 count = regs->al; @@ -101,7 +101,7 @@ basic_access(struct bregs *regs, u8 device, u16 command) irq_disable(); // Set nb of sector transferred - regs->al = GET_EBDA(ata.trsfsectors); + regs->al = GET_EBDA(sector_count); if (status != 0) { dprintf(1, "int13_harddisk: function %02x, error %d!\n" @@ -116,9 +116,9 @@ extended_access(struct bregs *regs, u8 device, u16 command) { // Get lba and check. u64 lba = GET_INT13EXT(regs, lba); - u8 type = GET_EBDA(ata.devices[device].type); + u8 type = GET_GLOBAL(ATA.devices[device].type); if (type == ATA_TYPE_ATA - && lba >= GET_EBDA(ata.devices[device].sectors)) { + && lba >= GET_GLOBAL(ATA.devices[device].sectors)) { dprintf(1, "int13_harddisk: function %02x. LBA out of range\n" , regs->ah); disk_ret(regs, DISK_RET_EPARAM); @@ -149,7 +149,7 @@ extended_access(struct bregs *regs, u8 device, u16 command) irq_disable(); - SET_INT13EXT(regs, count, GET_EBDA(ata.trsfsectors)); + SET_INT13EXT(regs, count, GET_EBDA(sector_count)); if (status != 0) { dprintf(1, "int13_harddisk: function %02x, error %d!\n" @@ -216,10 +216,10 @@ static void disk_1308(struct bregs *regs, u8 device) { // Get logical geometry from table - u16 nlc = GET_EBDA(ata.devices[device].lchs.cylinders); - u16 nlh = GET_EBDA(ata.devices[device].lchs.heads); - u16 nlspt = GET_EBDA(ata.devices[device].lchs.spt); - u16 count = GET_EBDA(ata.hdcount); + u16 nlc = GET_GLOBAL(ATA.devices[device].lchs.cylinders); + u16 nlh = GET_GLOBAL(ATA.devices[device].lchs.heads); + u16 nlspt = GET_GLOBAL(ATA.devices[device].lchs.spt); + u16 count = GET_GLOBAL(ATA.hdcount); nlc = nlc - 2; /* 0 based , last sector not used */ regs->al = 0; @@ -260,7 +260,7 @@ disk_1310(struct bregs *regs, u8 device) // should look at 40:8E also??? // Read the status from controller - u8 status = inb(GET_EBDA(ata.channels[device/2].iobase1) + ATA_CB_STAT); + u8 status = inb(GET_GLOBAL(ATA.channels[device/2].iobase1) + ATA_CB_STAT); if ( (status & ( ATA_CB_STAT_BSY | ATA_CB_STAT_RDY )) == ATA_CB_STAT_RDY ) disk_ret(regs, DISK_RET_SUCCESS); else @@ -286,9 +286,9 @@ static void disk_1315(struct bregs *regs, u8 device) { // Get logical geometry from table - u16 nlc = GET_EBDA(ata.devices[device].lchs.cylinders); - u16 nlh = GET_EBDA(ata.devices[device].lchs.heads); - u16 nlspt = GET_EBDA(ata.devices[device].lchs.spt); + u16 nlc = GET_GLOBAL(ATA.devices[device].lchs.cylinders); + u16 nlh = GET_GLOBAL(ATA.devices[device].lchs.heads); + u16 nlspt = GET_GLOBAL(ATA.devices[device].lchs.spt); // Compute sector count seen by int13 u32 lba = (u32)(nlc - 1) * (u32)nlh * (u32)nlspt; @@ -367,12 +367,12 @@ disk_1348(struct bregs *regs, u8 device) // EDD 1.x - u8 type = GET_EBDA(ata.devices[device].type); - u16 npc = GET_EBDA(ata.devices[device].pchs.cylinders); - u16 nph = GET_EBDA(ata.devices[device].pchs.heads); - u16 npspt = GET_EBDA(ata.devices[device].pchs.spt); - u64 lba = GET_EBDA(ata.devices[device].sectors); - u16 blksize = GET_EBDA(ata.devices[device].blksize); + u8 type = GET_GLOBAL(ATA.devices[device].type); + u16 npc = GET_GLOBAL(ATA.devices[device].pchs.cylinders); + u16 nph = GET_GLOBAL(ATA.devices[device].pchs.heads); + u16 npspt = GET_GLOBAL(ATA.devices[device].pchs.spt); + u64 lba = GET_GLOBAL(ATA.devices[device].sectors); + u16 blksize = GET_GLOBAL(ATA.devices[device].blksize); dprintf(DEBUG_HDL_13, "disk_1348 size=%d t=%d chs=%d,%d,%d lba=%d bs=%d\n" , size, type, npc, nph, npspt, (u32)lba, blksize); @@ -411,19 +411,19 @@ disk_1348(struct bregs *regs, u8 device) SET_INT13DPT(regs, dpte_segment, GET_BDA(ebda_seg)); SET_INT13DPT(regs, dpte_offset - , offsetof(struct extended_bios_data_area_s, ata.dpte)); + , offsetof(struct extended_bios_data_area_s, dpte)); // Fill in dpte u8 channel = device / 2; u8 slave = device % 2; - u16 iobase1 = GET_EBDA(ata.channels[channel].iobase1); - u16 iobase2 = GET_EBDA(ata.channels[channel].iobase2); - u8 irq = GET_EBDA(ata.channels[channel].irq); - u8 mode = GET_EBDA(ata.devices[device].mode); + u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1); + u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2); + u8 irq = GET_GLOBAL(ATA.channels[channel].irq); + u8 mode = GET_GLOBAL(ATA.devices[device].mode); u16 options = 0; if (type == ATA_TYPE_ATA) { - u8 translation = GET_EBDA(ata.devices[device].translation); + u8 translation = GET_GLOBAL(ATA.devices[device].translation); if (translation != ATA_TRANSLATION_NONE) { options |= 1<<3; // CHS translation if (translation == ATA_TRANSLATION_LBA) @@ -440,22 +440,22 @@ disk_1348(struct bregs *regs, u8 device) if (mode == ATA_MODE_PIO32) options |= 1<<7; - SET_EBDA(ata.dpte.iobase1, iobase1); - SET_EBDA(ata.dpte.iobase2, iobase2 + ATA_CB_DC); - SET_EBDA(ata.dpte.prefix, ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) + SET_EBDA(dpte.iobase1, iobase1); + SET_EBDA(dpte.iobase2, iobase2 + ATA_CB_DC); + SET_EBDA(dpte.prefix, ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | ATA_CB_DH_LBA)); - SET_EBDA(ata.dpte.unused, 0xcb); - SET_EBDA(ata.dpte.irq, irq); - SET_EBDA(ata.dpte.blkcount, 1); - SET_EBDA(ata.dpte.dma, 0); - SET_EBDA(ata.dpte.pio, 0); - SET_EBDA(ata.dpte.options, options); - SET_EBDA(ata.dpte.reserved, 0); - SET_EBDA(ata.dpte.revision, 0x11); + SET_EBDA(dpte.unused, 0xcb); + SET_EBDA(dpte.irq, irq); + SET_EBDA(dpte.blkcount, 1); + SET_EBDA(dpte.dma, 0); + SET_EBDA(dpte.pio, 0); + SET_EBDA(dpte.options, options); + SET_EBDA(dpte.reserved, 0); + SET_EBDA(dpte.revision, 0x11); u8 *p = MAKE_FARPTR(GET_BDA(ebda_seg) - , offsetof(struct extended_bios_data_area_s, ata.dpte)); - SET_EBDA(ata.dpte.checksum, -checksum(p, 15)); + , offsetof(struct extended_bios_data_area_s, dpte)); + SET_EBDA(dpte.checksum, -checksum(p, 15)); if (size < 66) { disk_ret(regs, DISK_RET_SUCCESS); @@ -473,7 +473,7 @@ disk_1348(struct bregs *regs, u8 device) SET_INT13DPT(regs, host_bus[2], 'I'); SET_INT13DPT(regs, host_bus[3], 0); - u32 bdf = GET_EBDA(ata.channels[channel].pci_bdf); + u32 bdf = GET_GLOBAL(ATA.channels[channel].pci_bdf); u32 path = (pci_bdf_to_bus(bdf) | (pci_bdf_to_dev(bdf) << 8) | (pci_bdf_to_fn(bdf) << 16)); SET_INT13DPT(regs, iface_path, path); @@ -603,7 +603,7 @@ get_device(struct bregs *regs, u8 iscd, u8 drive) } // Get the ata channel - u8 device = GET_EBDA(ata.idmap[iscd][drive]); + u8 device = GET_GLOBAL(ATA.idmap[iscd][drive]); // basic check : device has to be valid if (device >= CONFIG_MAX_ATA_DEVICES) { @@ -661,8 +661,8 @@ handle_13(struct bregs *regs) cdemu_134b(regs); return; } - if (GET_EBDA(cdemu.active)) { - if (drive == GET_EBDA(cdemu.emulated_drive)) { + if (GET_EBDA(cdemu_active)) { + if (drive == GET_GLOBAL(CDEMU.emulated_drive)) { cdemu_13(regs); return; } @@ -7,6 +7,7 @@ #define __DISK_H #include "types.h" // u8 +#include "config.h" // CONFIG_* #define DISK_RET_SUCCESS 0x00 #define DISK_RET_EPARAM 0x01 @@ -24,6 +25,11 @@ #define DISK_RET_EMEDIA 0xC0 #define DISK_RET_ENOTREADY 0xAA + +/**************************************************************** + * Interface structs + ****************************************************************/ + // Bios disk structures. struct int13ext_s { u8 size; @@ -96,6 +102,73 @@ void __disk_ret(const char *fname, int lineno, struct bregs *regs, u8 code); #define disk_ret(regs, code) \ __disk_ret(__func__, __LINE__, (regs), (code)) + +/**************************************************************** + * Global storage + ****************************************************************/ + +struct chs_s { + u16 heads; // # heads + u16 cylinders; // # cylinders + u16 spt; // # sectors / track +}; + +struct ata_channel_s { + u16 iobase1; // IO Base 1 + u16 iobase2; // IO Base 2 + u16 pci_bdf; + u8 irq; // IRQ +}; + +struct ata_device_s { + u8 type; // Detected type of ata (ata/atapi/none/unknown) + u8 device; // Detected type of attached devices (hd/cd/none) + u8 removable; // Removable device flag + u8 mode; // transfer mode : PIO 16/32 bits - IRQ - ISADMA - PCIDMA + u16 blksize; // block size + + u8 translation; // type of translation + struct chs_s lchs; // Logical CHS + struct chs_s pchs; // Physical CHS + + u64 sectors; // Total sectors count +}; + +struct ata_s { + // ATA channels info + struct ata_channel_s channels[CONFIG_MAX_ATA_INTERFACES]; + + // ATA devices info + struct ata_device_s devices[CONFIG_MAX_ATA_DEVICES]; + // + // map between bios hd/cd id and ata channels + u8 hdcount, cdcount; + u8 idmap[2][CONFIG_MAX_ATA_DEVICES]; +}; + +// ElTorito Device Emulation data +struct cdemu_s { + u8 media; + u8 emulated_drive; + u8 controller_index; + u16 device_spec; + u32 ilba; + u16 buffer_segment; + u16 load_segment; + u16 sector_count; + + // Virtual device + struct chs_s vdevice; +}; + + +/**************************************************************** + * Function defs + ****************************************************************/ + +// ata.c +extern struct ata_s ATA; + // floppy.c extern struct floppy_ext_dbt_s diskette_param_table2; void floppy_drive_setup(); @@ -107,6 +180,7 @@ void disk_13(struct bregs *regs, u8 device); void disk_13XX(struct bregs *regs, u8 device); // cdrom.c +extern struct cdemu_s CDEMU; int cdrom_read_emu(u16 device, u32 lba, u32 count, void *far_buffer); void cdrom_13(struct bregs *regs, u8 device); void cdemu_13(struct bregs *regs); |