From 9f0d94dee364ed9a9913e8fa7c0897a85014dc5c Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Sun, 13 Apr 2008 17:25:30 -0400 Subject: [PATCH] Move hard drive init from post.c to ata.c. --- src/ata.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/ata.h | 2 +- src/biosvar.h | 3 +- src/post.c | 84 ++----------------------------------------------- 4 files changed, 91 insertions(+), 85 deletions(-) diff --git a/src/ata.c b/src/ata.c index a438f54..9280f46 100644 --- a/src/ata.c +++ b/src/ata.c @@ -668,7 +668,7 @@ init_drive_unknown(int driveid) printf("ata%d %s: Unknown device\n", channel, slave ? " slave" : "master"); } -void +static void ata_detect() { #if CONFIG_MAX_ATA_INTERFACES > 0 @@ -762,3 +762,88 @@ ata_detect() // FIXME : should know about translation bits // FIXME : move hard_drive_post here } + +static void +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); + } +} + +static void +fill_hdinfo(int hdnum, u8 typecmos, u8 basecmos) +{ + u8 type = inb_cmos(typecmos); + if (type != 47) + // XXX - halt + return; + + SET_EBDA(fdpt[hdnum].precompensation, ((inb_cmos(basecmos+4) << 8) + | inb_cmos(basecmos+3))); + SET_EBDA(fdpt[hdnum].drive_control_byte, inb_cmos(basecmos+5)); + SET_EBDA(fdpt[hdnum].landing_zone, ((inb_cmos(basecmos+7) << 8) + | inb_cmos(basecmos+6))); + u16 cyl = (inb_cmos(basecmos+1) << 8) | inb_cmos(basecmos+0); + u8 heads = inb_cmos(basecmos+2); + u8 sectors = inb_cmos(basecmos+8); + if (cyl < 1024) { + // no logical CHS mapping used, just physical CHS + // use Standard Fixed Disk Parameter Table (FDPT) + SET_EBDA(fdpt[hdnum].cylinders, cyl); + SET_EBDA(fdpt[hdnum].heads, heads); + SET_EBDA(fdpt[hdnum].sectors, sectors); + return; + } + + // complies with Phoenix style Translated Fixed Disk Parameter + // Table (FDPT) + SET_EBDA(fdpt[hdnum].phys_cylinders, cyl); + SET_EBDA(fdpt[hdnum].phys_heads, heads); + SET_EBDA(fdpt[hdnum].phys_sectors, sectors); + SET_EBDA(fdpt[hdnum].sectors, sectors); + SET_EBDA(fdpt[hdnum].a0h_signature, 0xa0); + if (cyl > 8192) { + cyl >>= 4; + heads <<= 4; + } else if (cyl > 4096) { + cyl >>= 3; + heads <<= 3; + } else if (cyl > 2048) { + cyl >>= 2; + heads <<= 2; + } + SET_EBDA(fdpt[hdnum].cylinders, cyl); + SET_EBDA(fdpt[hdnum].heads, heads); + u8 *p = MAKE_FARPTR(SEG_EBDA, offsetof(struct extended_bios_data_area_s + , fdpt[hdnum])); + u8 sum = checksum(p, FIELD_SIZEOF(struct extended_bios_data_area_s + , fdpt[hdnum]) - 1); + SET_EBDA(fdpt[hdnum].checksum, -sum); +} + +void +hard_drive_setup() +{ + outb(0x0a, PORT_HD_DATA); // 0000 1010 = reserved, disable IRQ 14 + SET_BDA(disk_count, 1); + SET_BDA(disk_control_byte, 0xc0); + + // move disk geometry data from CMOS to EBDA disk parameter table(s) + u8 diskinfo = inb_cmos(CMOS_DISK_DATA); + if ((diskinfo & 0xf0) == 0xf0) + // Fill EBDA table for hard disk 0. + fill_hdinfo(0, CMOS_DISK_DRIVE1_TYPE, CMOS_DISK_DRIVE1_CYL); + if ((diskinfo & 0x0f) == 0x0f) + // XXX - bochs halts on any other type + // Fill EBDA table for hard disk 1. + fill_hdinfo(1, CMOS_DISK_DRIVE2_TYPE, CMOS_DISK_DRIVE2_CYL); + + if (CONFIG_ATA) { + ata_init(); + ata_detect(); + } +} diff --git a/src/ata.h b/src/ata.h index 54a2434..a778120 100644 --- a/src/ata.h +++ b/src/ata.h @@ -18,6 +18,6 @@ int ata_cmd_packet(int driveid, u8 *cmdbuf, u8 cmdlen , u32 length, void *far_buffer); int cdrom_read(int driveid, u32 lba, u32 count, void *far_buffer); int cdrom_read_512(int driveid, u32 lba, u32 count, void *far_buffer); -void ata_detect(); +void hard_drive_setup(); #endif /* __ATA_H */ diff --git a/src/biosvar.h b/src/biosvar.h index 1c791dc..9528523 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -252,8 +252,7 @@ struct extended_bios_data_area_s { u8 other1[0x0d]; // 0x3d - struct fdpt_s fdpt0; - struct fdpt_s fdpt1; + struct fdpt_s fdpt[2]; // 0x5d u8 other2[0xC4]; diff --git a/src/post.c b/src/post.c index f8a3de9..2671144 100644 --- a/src/post.c +++ b/src/post.c @@ -75,10 +75,10 @@ init_ebda() SET_BDA(ebda_seg, SEG_EBDA); SET_BDA(ivecs[0x41].seg, SEG_EBDA); SET_BDA(ivecs[0x41].offset - , offsetof(struct extended_bios_data_area_s, fdpt0)); + , offsetof(struct extended_bios_data_area_s, fdpt[0])); SET_BDA(ivecs[0x46].seg, SEG_EBDA); SET_BDA(ivecs[0x41].offset - , offsetof(struct extended_bios_data_area_s, fdpt1)); + , offsetof(struct extended_bios_data_area_s, fdpt[1])); } static void @@ -183,80 +183,6 @@ pic_setup() outb(0x9f, PORT_PIC2_DATA); } -static void -ata_init() -{ - // hdidmap and cdidmap init. - u8 device; - for (device=0; device < CONFIG_MAX_ATA_DEVICES; device++) { - ebda->ata.idmap[0][device] = CONFIG_MAX_ATA_DEVICES; - ebda->ata.idmap[1][device] = CONFIG_MAX_ATA_DEVICES; - } -} - -static void -fill_hdinfo(struct fdpt_s *info, u8 typecmos, u8 basecmos) -{ - u8 type = inb_cmos(typecmos); - if (type != 47) - // XXX - halt - return; - - info->precompensation = (inb_cmos(basecmos+4) << 8) | inb_cmos(basecmos+3); - info->drive_control_byte = inb_cmos(basecmos+5); - info->landing_zone = (inb_cmos(basecmos+7) << 8) | inb_cmos(basecmos+6); - u16 cyl = (inb_cmos(basecmos+1) << 8) | inb_cmos(basecmos+0); - u8 heads = inb_cmos(basecmos+2); - u8 sectors = inb_cmos(basecmos+8); - if (cyl < 1024) { - // no logical CHS mapping used, just physical CHS - // use Standard Fixed Disk Parameter Table (FDPT) - info->cylinders = cyl; - info->heads = heads; - info->sectors = sectors; - return; - } - - // complies with Phoenix style Translated Fixed Disk Parameter - // Table (FDPT) - info->phys_cylinders = cyl; - info->phys_heads = heads; - info->phys_sectors = sectors; - info->sectors = sectors; - info->a0h_signature = 0xa0; - if (cyl > 8192) { - cyl >>= 4; - heads <<= 4; - } else if (cyl > 4096) { - cyl >>= 3; - heads <<= 3; - } else if (cyl > 2048) { - cyl >>= 2; - heads <<= 2; - } - info->cylinders = cyl; - info->heads = heads; - info->checksum = -checksum((u8*)info, sizeof(*info)-1); -} - -static void -hard_drive_post() -{ - outb(0x0a, PORT_HD_DATA); // 0000 1010 = reserved, disable IRQ 14 - SET_BDA(disk_count, 1); - SET_BDA(disk_control_byte, 0xc0); - - // move disk geometry data from CMOS to EBDA disk parameter table(s) - u8 diskinfo = inb_cmos(CMOS_DISK_DATA); - if ((diskinfo & 0xf0) == 0xf0) - // Fill EBDA table for hard disk 0. - fill_hdinfo(&ebda->fdpt0, CMOS_DISK_DRIVE1_TYPE, CMOS_DISK_DRIVE1_CYL); - if ((diskinfo & 0x0f) == 0x0f) - // XXX - bochs halts on any other type - // Fill EBDA table for hard disk 1. - fill_hdinfo(&ebda->fdpt1, CMOS_DISK_DRIVE2_TYPE, CMOS_DISK_DRIVE2_CYL); -} - static void init_boot_vectors() { @@ -362,11 +288,7 @@ post() rombios32_init(); floppy_drive_setup(); - hard_drive_post(); - if (CONFIG_ATA) { - ata_init(); - ata_detect(); - } + hard_drive_setup(); init_boot_vectors(); -- 2.25.1