diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2008-12-26 23:50:17 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2008-12-26 23:50:17 -0500 |
commit | 4d7c37e12ef4ceb6903dd76ee700beb99fbf5f8e (patch) | |
tree | 775ea50649f399752e929bd7cdcdc14e42a548c6 /src | |
parent | 4735877249b30502e4c816bf1dc1a2c0e16be68e (diff) | |
download | seabios-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.c | 44 | ||||
-rw-r--r-- | src/biosvar.h | 15 | ||||
-rw-r--r-- | src/config.h | 1 | ||||
-rw-r--r-- | src/disk.c | 4 | ||||
-rw-r--r-- | src/optionroms.c | 7 | ||||
-rw-r--r-- | src/post.c | 22 |
6 files changed, 47 insertions, 46 deletions
@@ -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) @@ -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; @@ -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++; |