The dpte, cdrom locks, and disk sector count remain in the ebda.
Also, enhance SET_GLOBAL macro to avoid unused variable warnings.
#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
#define IDE_TIMEOUT 32000u //32 seconds max for IDE ops
+struct ata_s ATA VAR16;
+
/****************************************************************
* Helper functions
{
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
// 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);
}
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)
, 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 (;;) {
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
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;
}
{
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;
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];
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);
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;
}
// 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;
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);
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];
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))
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;
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;
// 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
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;
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++;
}
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++;
}
}
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);
} while (0)
-/****************************************************************
- * 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)
****************************************************************/
* 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;
// 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;
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)
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;
#include "bregs.h" // struct bregs
#include "biosvar.h" // GET_EBDA
+struct cdemu_s CDEMU VAR16;
+
/****************************************************************
* CDROM functions
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);
}
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);
}
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);
}
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;
__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);
}
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;
// 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;
{
//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
{
// 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);
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;
}
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
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;
}
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;
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));
// 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;
}
// 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;
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;
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"
{
// 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);
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"
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;
// 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
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;
// 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);
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)
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);
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);
}
// 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) {
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;
}
#define __DISK_H
#include "types.h" // u8
+#include "config.h" // CONFIG_*
#define DISK_RET_SUCCESS 0x00
#define DISK_RET_EPARAM 0x01
#define DISK_RET_EMEDIA 0xC0
#define DISK_RET_ENOTREADY 0xAA
+
+/****************************************************************
+ * Interface structs
+ ****************************************************************/
+
// Bios disk structures.
struct int13ext_s {
u8 size;
#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();
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);