aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2008-12-26 23:50:17 -0500
committerKevin O'Connor <kevin@koconnor.net>2008-12-26 23:50:17 -0500
commit4d7c37e12ef4ceb6903dd76ee700beb99fbf5f8e (patch)
tree775ea50649f399752e929bd7cdcdc14e42a548c6 /src
parent4735877249b30502e4c816bf1dc1a2c0e16be68e (diff)
downloadseabios-4d7c37e12ef4ceb6903dd76ee700beb99fbf5f8e.tar.gz
Support a relocatable ebda segment.
Some option roms will try to relocate the ebda. Also fix an apparent typo in the assignment of ivecs[0x46].
Diffstat (limited to 'src')
-rw-r--r--src/ata.c44
-rw-r--r--src/biosvar.h15
-rw-r--r--src/config.h1
-rw-r--r--src/disk.c4
-rw-r--r--src/optionroms.c7
-rw-r--r--src/post.c22
6 files changed, 47 insertions, 46 deletions
diff --git a/src/ata.c b/src/ata.c
index 53f91963..a8aee7b8 100644
--- a/src/ata.c
+++ b/src/ata.c
@@ -600,20 +600,21 @@ fill_fdpt(int driveid)
if (driveid > 1)
return;
- u16 nlc = GET_EBDA(ata.devices[driveid].lchs.cylinders);
- u16 nlh = GET_EBDA(ata.devices[driveid].lchs.heads);
- u16 nlspt = GET_EBDA(ata.devices[driveid].lchs.spt);
-
- u16 npc = GET_EBDA(ata.devices[driveid].pchs.cylinders);
- u16 nph = GET_EBDA(ata.devices[driveid].pchs.heads);
- u16 npspt = GET_EBDA(ata.devices[driveid].pchs.spt);
-
- SET_EBDA(fdpt[driveid].precompensation, 0xffff);
- SET_EBDA(fdpt[driveid].drive_control_byte, 0xc0 | ((nph > 8) << 3));
- SET_EBDA(fdpt[driveid].landing_zone, npc);
- SET_EBDA(fdpt[driveid].cylinders, nlc);
- SET_EBDA(fdpt[driveid].heads, nlh);
- SET_EBDA(fdpt[driveid].sectors, nlspt);
+ 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 npc = ebda->ata.devices[driveid].pchs.cylinders;
+ u16 nph = ebda->ata.devices[driveid].pchs.heads;
+ u16 npspt = ebda->ata.devices[driveid].pchs.spt;
+
+ ebda->fdpt[driveid].precompensation = 0xffff;
+ ebda->fdpt[driveid].drive_control_byte = 0xc0 | ((nph > 8) << 3);
+ ebda->fdpt[driveid].landing_zone = npc;
+ ebda->fdpt[driveid].cylinders = nlc;
+ ebda->fdpt[driveid].heads = nlh;
+ ebda->fdpt[driveid].sectors = nlspt;
if (nlc == npc && nlh == nph && nlspt == npspt)
// no logical CHS mapping used, just physical CHS
@@ -622,17 +623,14 @@ fill_fdpt(int driveid)
// complies with Phoenix style Translated Fixed Disk Parameter
// Table (FDPT)
- SET_EBDA(fdpt[driveid].phys_cylinders, npc);
- SET_EBDA(fdpt[driveid].phys_heads, nph);
- SET_EBDA(fdpt[driveid].phys_sectors, npspt);
- SET_EBDA(fdpt[driveid].a0h_signature, 0xa0);
+ ebda->fdpt[driveid].phys_cylinders = npc;
+ ebda->fdpt[driveid].phys_heads = nph;
+ ebda->fdpt[driveid].phys_sectors = npspt;
+ ebda->fdpt[driveid].a0h_signature = 0xa0;
// Checksum structure.
- u8 *p = MAKE_FARPTR(SEG_EBDA, offsetof(struct extended_bios_data_area_s
- , fdpt[driveid]));
- u8 sum = checksum(p, FIELD_SIZEOF(struct extended_bios_data_area_s
- , fdpt[driveid]) - 1);
- SET_EBDA(fdpt[driveid].checksum, -sum);
+ u8 sum = checksum((u8*)&ebda->fdpt[driveid], sizeof(ebda->fdpt[driveid])-1);
+ ebda->fdpt[driveid].checksum = -sum;
}
static u8
diff --git a/src/biosvar.h b/src/biosvar.h
index f2cb47f6..84c46282 100644
--- a/src/biosvar.h
+++ b/src/biosvar.h
@@ -294,14 +294,19 @@ struct extended_bios_data_area_s {
u8 resume_stack[128] __aligned(8);
} PACKED;
-#define EBDA_SIZE DIV_ROUND_UP(sizeof(struct extended_bios_data_area_s), 1024)
-#define BASE_MEM_IN_K (640 - EBDA_SIZE)
-
// Accessor functions
#define GET_EBDA(var) \
- GET_FARVAR(SEG_EBDA, ((struct extended_bios_data_area_s *)0)->var)
+ GET_FARVAR(GET_BDA(ebda_seg), ((struct extended_bios_data_area_s *)0)->var)
#define SET_EBDA(var, val) \
- SET_FARVAR(SEG_EBDA, ((struct extended_bios_data_area_s *)0)->var, (val))
+ SET_FARVAR(GET_BDA(ebda_seg), ((struct extended_bios_data_area_s *)0)->var, (val))
+static inline struct extended_bios_data_area_s *
+get_ebda_ptr()
+{
+ extern void *__force_link_error__get_ebda_ptr_only_in_32bit();
+ if (MODE16)
+ return __force_link_error__get_ebda_ptr_only_in_32bit();
+ return (void*)MAKE_FARPTR(GET_BDA(ebda_seg), 0);
+}
/****************************************************************
diff --git a/src/config.h b/src/config.h
index 1a1499ab..13a023a7 100644
--- a/src/config.h
+++ b/src/config.h
@@ -108,7 +108,6 @@
// Important real-mode segments
#define SEG_BIOS 0xf000
-#define SEG_EBDA 0x9fc0
#define SEG_BDA 0x0000
// Segment definitions in protected mode (see rombios32_gdt in romlayout.S)
diff --git a/src/disk.c b/src/disk.c
index 23501ff3..da12d392 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -409,7 +409,7 @@ disk_1348(struct bregs *regs, u8 device)
SET_INT13DPT(regs, size, 30);
- SET_INT13DPT(regs, dpte_segment, SEG_EBDA);
+ SET_INT13DPT(regs, dpte_segment, GET_BDA(ebda_seg));
SET_INT13DPT(regs, dpte_offset
, offsetof(struct extended_bios_data_area_s, ata.dpte));
@@ -453,7 +453,7 @@ disk_1348(struct bregs *regs, u8 device)
SET_EBDA(ata.dpte.reserved, 0);
SET_EBDA(ata.dpte.revision, 0x11);
- u8 *p = MAKE_FARPTR(SEG_EBDA
+ 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));
diff --git a/src/optionroms.c b/src/optionroms.c
index 89381634..b7bc1108 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -96,10 +96,6 @@ callrom(struct rom_header *rom, u16 offset, u16 bdf)
call16big(&br);
debug_serial_setup();
-
- if (GET_BDA(ebda_seg) != SEG_EBDA)
- BX_PANIC("Option rom at %x:%x attempted to move ebda from %x to %x\n"
- , seg, offset, SEG_EBDA, GET_BDA(ebda_seg));
}
// Verify that an option rom looks valid
@@ -154,14 +150,13 @@ get_pci_rom(struct rom_header *rom)
static void
add_ipl(struct rom_header *rom, struct pnp_data *pnp)
{
-#define ebda ((struct extended_bios_data_area_s *)MAKE_FARPTR(SEG_EBDA, 0))
-
// Found a device that thinks it can boot the system. Record
// its BEV and product name string.
if (! CONFIG_BOOT)
return;
+ struct extended_bios_data_area_s *ebda = get_ebda_ptr();
if (ebda->ipl.count >= ARRAY_SIZE(ebda->ipl.table))
return;
diff --git a/src/post.c b/src/post.c
index f55d53d0..59516446 100644
--- a/src/post.c
+++ b/src/post.c
@@ -19,7 +19,6 @@
#include "bregs.h" // struct bregs
#define bda ((struct bios_data_area_s *)MAKE_FARPTR(SEG_BDA, 0))
-#define ebda ((struct extended_bios_data_area_s *)MAKE_FARPTR(SEG_EBDA, 0))
void
__set_irq(int vector, void *loc)
@@ -39,8 +38,6 @@ init_bda()
dprintf(3, "init bda\n");
memset(bda, 0, sizeof(*bda));
- SET_BDA(mem_size_kb, BASE_MEM_IN_K);
-
// Initialize all vectors to a dummy handler.
int i;
for (i=0; i<256; i++)
@@ -78,14 +75,19 @@ init_bda()
static void
init_ebda()
{
+ int esize = DIV_ROUND_UP(sizeof(struct extended_bios_data_area_s), 1024);
+ SET_BDA(mem_size_kb, 640 - esize);
+ u16 eseg = FARPTR_TO_SEG((640 - esize) * 1024);
+ SET_BDA(ebda_seg, eseg);
+
+ struct extended_bios_data_area_s *ebda = get_ebda_ptr();
memset(ebda, 0, sizeof(*ebda));
- ebda->size = EBDA_SIZE;
- SET_BDA(ebda_seg, SEG_EBDA);
- SET_BDA(ivecs[0x41].seg, SEG_EBDA);
+ ebda->size = esize;
+ SET_BDA(ivecs[0x41].seg, eseg);
SET_BDA(ivecs[0x41].offset
, offsetof(struct extended_bios_data_area_s, fdpt[0]));
- SET_BDA(ivecs[0x46].seg, SEG_EBDA);
- SET_BDA(ivecs[0x41].offset
+ SET_BDA(ivecs[0x46].seg, eseg);
+ SET_BDA(ivecs[0x46].offset
, offsetof(struct extended_bios_data_area_s, fdpt[1]));
}
@@ -123,7 +125,8 @@ ram_probe(void)
add_e820(0xa0000, 0x50000, E820_HOLE);
// Mark known areas as reserved.
- add_e820((u32)MAKE_FARPTR(SEG_EBDA, 0), EBDA_SIZE * 1024, E820_RESERVED);
+ add_e820((u32)MAKE_FARPTR(GET_BDA(ebda_seg), 0), GET_EBDA(size) * 1024
+ , E820_RESERVED);
add_e820(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED);
dprintf(1, "ram_size=0x%08x\n", GET_EBDA(ram_size));
@@ -153,6 +156,7 @@ init_boot_vectors()
dprintf(3, "init boot device ordering\n");
// Floppy drive
+ struct extended_bios_data_area_s *ebda = get_ebda_ptr();
struct ipl_entry_s *ip = &ebda->ipl.table[0];
ip->type = IPL_TYPE_FLOPPY;
ip++;