This patch series updates the SeaBIOS' low-memory allocation scheme so that it no longer uses the EBDA or the 9-segment for internal low memory allocations. Instead, the e-segment is used where SeaBIOS requires read/writable "low" memory.
There is now plenty of space in the e-segment (there has been ever since SeaBIOS was updated to relocate its initialization code), while using 9-segment space can reserve the memory from OS use (in particular on older operating systems). Also, using the 9-segment (and indirectly the EBDA) is more fragile as it requires handling of a relocatable EBDA.
As a result of this change, SeaBIOS will be able to allocate larger amounts of low-memory. Indeed, the size of the "extra stack" for 16bit code is increased from 512 bytes to 2K in this series.
Changes in v2: * Fixed ehci error resulting from changes to stack alignment * Introduce new GET/SET_LOW and GET/SET_LOWFLAT macros (which mirror GET_GLOBAL and GET_GLOBALFLAT) which produce better 16bit code.
-Kevin
Kevin O'Connor (9): Use the e-segment instead of the 9-segment for bios "low mem". Add mechanism to declare variables as "low mem" and use for extra stack. Convert timer code EBDA variables to VARLOW variables. Convert boot code EBDA variables to VARLOW variables. Convert ps2 code EBDA variables to VARLOW variables. Convert USB keyboard code EBDA variables to VARLOW variables. Convert disk code EBDA variables to VARLOW variables. EBDA cleanups. Convert GET/SET_FLATPTR() accesses to "low mem" to GET/SET_LOWFLAT().
src/acpi.c | 2 +- src/ahci.c | 2 +- src/asm-offsets.c | 8 -- src/ata.c | 7 +- src/biosvar.h | 100 ++++------------ src/block.c | 5 +- src/blockcmd.h | 2 + src/boot.c | 19 ++-- src/bootsplash.c | 1 - src/cdrom.c | 84 +++++++------- src/clock.c | 32 +++--- src/config.h | 2 + src/coreboot.c | 3 +- src/disk.c | 75 +++++------- src/disk.h | 38 ++++++- src/memmap.c | 2 +- src/mouse.c | 31 +++--- src/mtrr.c | 2 +- src/optionroms.c | 14 +-- src/pcibios.c | 2 +- src/pciinit.c | 3 +- src/pirtable.c | 2 +- src/pmm.c | 116 ++++------------- src/post.c | 50 ++++++-- src/ps2port.c | 19 ++-- src/romlayout.S | 8 +- src/shadow.c | 4 +- src/smbios.c | 1 - src/stacks.c | 15 ++- src/types.h | 4 + src/usb-ehci.c | 40 +++--- src/usb-hid.c | 17 ++- src/usb-ohci.c | 26 ++-- src/usb-uhci.c | 43 +++---- src/util.h | 3 +- src/xen.h | 3 +- tools/layoutrom.py | 349 +++++++++++++++++++++++++++++----------------------- 37 files changed, 551 insertions(+), 583 deletions(-)
Use the e-segment for ZoneLow allocations. There is plenty of e-segment space (there has been since SeaBIOS supported code relocation), while using the 9-segment space can impact old real-mode applications.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/config.h | 1 + src/optionroms.c | 14 +----- src/pmm.c | 116 ++++++++++++----------------------------------------- src/shadow.c | 4 +- src/util.h | 2 +- 5 files changed, 34 insertions(+), 103 deletions(-)
diff --git a/src/config.h b/src/config.h index bbacae7..521469b 100644 --- a/src/config.h +++ b/src/config.h @@ -38,6 +38,7 @@ #define BUILD_ROM_START 0xc0000 #define BUILD_BIOS_ADDR 0xf0000 #define BUILD_BIOS_SIZE 0x10000 +#define BUILD_LOWMEM_SIZE 0x8000 // 32KB for shadow ram copying (works around emulator deficiencies) #define BUILD_BIOS_TMP_ADDR 0x30000 #define BUILD_SMM_INIT_ADDR 0x38000 diff --git a/src/optionroms.c b/src/optionroms.c index 06db1c1..5ce8af8 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -16,12 +16,10 @@ #include "paravirt.h" // qemu_cfg_* #include "optionroms.h" // struct rom_header
-/**************************************************************** - * Definitions - ****************************************************************/ - // The end of the last deployed rom. u32 RomEnd = BUILD_ROM_START; +// The maximum memory location a rom may extend to. +u32 RomTop;
/**************************************************************** @@ -120,15 +118,9 @@ get_pci_rom(struct rom_header *rom) return pd; }
-// Return start of code in 0xc0000-0xf0000 space. -static inline u32 _max_rom(void) { - extern u8 code32flat_start[], code32init_end[]; - return CONFIG_RELOCATE_INIT ? (u32)code32init_end : (u32)code32flat_start; -} // Return the memory position up to which roms may be located. static inline u32 max_rom(void) { - u32 end = _max_rom(); - return end > BUILD_BIOS_ADDR ? BUILD_BIOS_ADDR : end; + return RomTop; }
// Copy a rom to its permanent location below 1MiB diff --git a/src/pmm.c b/src/pmm.c index c649fd8..1648bf2 100644 --- a/src/pmm.c +++ b/src/pmm.c @@ -9,6 +9,7 @@ #include "memmap.h" // struct e820entry #include "farptr.h" // GET_FARVAR #include "biosvar.h" // GET_BDA +#include "optionroms.h" // OPTION_ROM_ALIGN
// Information on a reserved area. struct allocinfo_s { @@ -164,6 +165,15 @@ findLast(struct zone_s *zone) * Setup ****************************************************************/
+// Return start of code in 0xc0000-0xf0000 space. +static inline u32 lowmemend(void) { + extern u8 code32flat_start[], code32init_end[]; + u32 end = CONFIG_RELOCATE_INIT ? (u32)code32init_end : (u32)code32flat_start; + return end > BUILD_BIOS_ADDR ? BUILD_BIOS_ADDR : end; +} + +#define OPROM_HEADER_RESERVE 16 + void malloc_setup(void) { @@ -194,7 +204,9 @@ malloc_setup(void) // Populate other regions addSpace(&ZoneTmpLow, (void*)BUILD_STACK_ADDR, (void*)BUILD_EBDA_MINIMUM); addSpace(&ZoneFSeg, BiosTableSpace, &BiosTableSpace[CONFIG_MAX_BIOSTABLE]); - addSpace(&ZoneLow, (void*)BUILD_LOWRAM_END, (void*)BUILD_LOWRAM_END); + u32 lowend = lowmemend(); + RomTop = ALIGN_DOWN(lowend-BUILD_LOWMEM_SIZE, OPTION_ROM_ALIGN); + addSpace(&ZoneLow, (void*)RomTop + OPROM_HEADER_RESERVE, (void*)lowend); if (highram) { addSpace(&ZoneHigh, (void*)highram , (void*)highram + CONFIG_MAX_HIGHTABLE); @@ -232,12 +244,21 @@ malloc_finalize(void) ASSERT32FLAT(); dprintf(3, "malloc finalize\n");
- // Reserve more low-mem if needed. - u32 endlow = GET_BDA(mem_size_kb)*1024; - add_e820(endlow, BUILD_LOWRAM_END-endlow, E820_RESERVED); + // Place an optionrom signature around used low mem area. + struct allocinfo_s *info = findLast(&ZoneLow); + u32 base = BUILD_BIOS_ADDR; + if (info && info->allocend < (void*)BUILD_BIOS_ADDR) { + base = ALIGN_DOWN((u32)info->allocend - OPROM_HEADER_RESERVE + , OPTION_ROM_ALIGN); + struct rom_header *dummyrom = (void*)base; + dummyrom->signature = OPTION_ROM_SIGNATURE; + dummyrom->size = (BUILD_BIOS_ADDR - base) / 512; + } + memset((void*)RomEnd, 0, base-RomEnd); + dprintf(1, "Space available for UMB: %08x-%08x\n", RomEnd, base);
// Give back unused high ram. - struct allocinfo_s *info = findLast(&ZoneHigh); + info = findLast(&ZoneHigh); if (info) { u32 giveback = ALIGN_DOWN(info->allocend - info->dataend, PAGE_SIZE); add_e820((u32)info->dataend, giveback, E820_RAM); @@ -247,89 +268,6 @@ malloc_finalize(void)
/**************************************************************** - * ebda movement - ****************************************************************/ - -// Move ebda -static int -relocate_ebda(u32 newebda, u32 oldebda, u8 ebda_size) -{ - u32 lowram = GET_BDA(mem_size_kb) * 1024; - if (oldebda != lowram) - // EBDA isn't at end of ram - give up. - return -1; - - // Do copy - memmove((void*)newebda, (void*)oldebda, ebda_size * 1024); - - // Update indexes - dprintf(1, "ebda moved from %x to %x\n", oldebda, newebda); - SET_BDA(mem_size_kb, newebda / 1024); - SET_BDA(ebda_seg, FLATPTR_TO_SEG(newebda)); - return 0; -} - -// Support expanding the ZoneLow dynamically. -static void -zonelow_expand(u32 size, u32 align) -{ - struct allocinfo_s *info = findLast(&ZoneLow); - if (!info) - return; - u32 oldpos = (u32)info->allocend; - u32 newpos = ALIGN_DOWN(oldpos - size, align); - u32 bottom = (u32)info->dataend; - if (newpos >= bottom && newpos <= oldpos) - // Space already present. - return; - u16 ebda_seg = get_ebda_seg(); - u32 ebda_pos = (u32)MAKE_FLATPTR(ebda_seg, 0); - u8 ebda_size = GET_EBDA2(ebda_seg, size); - u32 ebda_end = ebda_pos + ebda_size * 1024; - if (ebda_end != bottom) - // Something else is after ebda - can't use any existing space. - newpos = ALIGN_DOWN(ebda_end - size, align); - u32 newbottom = ALIGN_DOWN(newpos, 1024); - u32 newebda = ALIGN_DOWN(newbottom - ebda_size * 1024, 1024); - if (newebda < BUILD_EBDA_MINIMUM) - // Not enough space. - return; - - // Move ebda - int ret = relocate_ebda(newebda, ebda_pos, ebda_size); - if (ret) - return; - - // Update zone - if (ebda_end == bottom) { - info->data = (void*)newbottom; - info->dataend = (void*)newbottom; - } else - addSpace(&ZoneLow, (void*)newbottom, (void*)ebda_end); -} - -// Check if can expand the given zone to fulfill an allocation -static void * -allocExpandSpace(struct zone_s *zone, u32 size, u32 align - , struct allocinfo_s *fill) -{ - void *data = allocSpace(zone, size, align, fill); - if (data || zone != &ZoneLow) - return data; - - // Make sure to not move ebda while an optionrom is running. - if (unlikely(wait_preempt())) { - data = allocSpace(zone, size, align, fill); - if (data) - return data; - } - - zonelow_expand(size, align); - return allocSpace(zone, size, align, fill); -} - - -/**************************************************************** * tracked memory allocations ****************************************************************/
@@ -352,7 +290,7 @@ pmm_malloc(struct zone_s *zone, u32 handle, u32 size, u32 align) }
// Find and reserve space for main allocation - void *data = allocExpandSpace(zone, size, align, &detail->datainfo); + void *data = allocSpace(zone, size, align, &detail->datainfo); if (!data) { freeSpace(&detail->detailinfo); return NULL; diff --git a/src/shadow.c b/src/shadow.c index c0c8cc2..70f04c5 100644 --- a/src/shadow.c +++ b/src/shadow.c @@ -83,8 +83,8 @@ make_bios_readonly_intel(u16 bdf, u32 pam0) for (i=0; i<6; i++) { u32 mem = BUILD_ROM_START + i * 32*1024; u32 pam = pam0 + 1 + i; - if (RomEnd <= mem + 16*1024) { - if (RomEnd > mem) + if (RomEnd <= mem + 16*1024 || RomTop <= mem + 32*1024) { + if (RomEnd > mem && RomTop > mem + 16*1024) pci_config_writeb(bdf, pam, 0x31); break; } diff --git a/src/util.h b/src/util.h index 70d3c4c..04de66b 100644 --- a/src/util.h +++ b/src/util.h @@ -400,7 +400,7 @@ void call_bcv(u16 seg, u16 ip); void optionrom_setup(void); void vga_setup(void); void s3_resume_vga_init(void); -extern u32 RomEnd; +extern u32 RomEnd, RomTop; extern int ScreenAndDebug;
// bootsplash.c
Add a mechanism (VARLOW declaration) to make a variable reside in the low memory (e-segment) area. This is useful for runtime variables that need to be accessed from 16bit code and need to be modifiable during runtime.
Move the 16bit "extra stack" from the EBDA to the low memory area using this declaration mechanism. Also increase the size of this stack from 512 bytes to 2048 bytes.
This also reworks tools/layoutrom.py a bit.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/asm-offsets.c | 8 -- src/ata.c | 7 +- src/biosvar.h | 24 +++-- src/block.c | 4 +- src/config.h | 1 + src/post.c | 48 +++++-- src/romlayout.S | 8 +- src/stacks.c | 15 ++- src/types.h | 4 + src/util.h | 1 + tools/layoutrom.py | 349 +++++++++++++++++++++++++++++----------------------- 11 files changed, 267 insertions(+), 202 deletions(-)
diff --git a/src/asm-offsets.c b/src/asm-offsets.c index 5035cef..b98f3b5 100644 --- a/src/asm-offsets.c +++ b/src/asm-offsets.c @@ -2,7 +2,6 @@
#include "gen-defs.h" // OFFSET #include "bregs.h" // struct bregs -#include "biosvar.h" // struct bios_data_area_s
/* workaround for a warning with -Wmissing-prototypes */ void foo(void) VISIBLE16; @@ -21,11 +20,4 @@ void foo(void) OFFSET(BREGS_edi, bregs, edi); OFFSET(BREGS_flags, bregs, flags); OFFSET(BREGS_code, bregs, code); - - COMMENT("BDA"); - OFFSET(BDA_ebda_seg, bios_data_area_s, ebda_seg); - - COMMENT("EBDA"); - DEFINE(EBDA_OFFSET_TOP_STACK, EBDA_OFFSET_TOP_STACK); - DEFINE(EBDA_SEGMENT_START, EBDA_SEGMENT_START); } diff --git a/src/ata.c b/src/ata.c index c37691a..b261bfe 100644 --- a/src/ata.c +++ b/src/ata.c @@ -10,7 +10,7 @@ #include "util.h" // dprintf #include "cmos.h" // inb_cmos #include "pic.h" // enable_hwirq -#include "biosvar.h" // GET_EBDA +#include "biosvar.h" // GET_GLOBAL #include "pci.h" // foreachpci #include "pci_ids.h" // PCI_CLASS_STORAGE_OTHER #include "pci_regs.h" // PCI_INTERRUPT_LINE @@ -379,6 +379,7 @@ struct sff_dma_prd { static int ata_try_dma(struct disk_op_s *op, int iswrite, int blocksize) { + ASSERT16(); if (! CONFIG_ATA_DMA) return -1; u32 dest = (u32)op->buf_fl; @@ -396,9 +397,7 @@ ata_try_dma(struct disk_op_s *op, int iswrite, int blocksize) return -1;
// Build PRD dma structure. - struct sff_dma_prd *dma = MAKE_FLATPTR( - get_ebda_seg() - , (void*)offsetof(struct extended_bios_data_area_s, extra_stack)); + struct sff_dma_prd *dma = MAKE_FLATPTR(SEG_LOW, ExtraStack); struct sff_dma_prd *origdma = dma; while (bytes) { if (dma >= &origdma[16]) diff --git a/src/biosvar.h b/src/biosvar.h index b6f7174..88b3257 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -242,9 +242,6 @@ struct extended_bios_data_area_s { /* TSC emulation timekeepers */ u64 tsc_8254; int last_tsc_8254; - - // Stack space available for code that needs it. - u8 extra_stack[512] __aligned(8); } PACKED;
// The initial size and location of EBDA @@ -272,11 +269,6 @@ get_ebda_ptr(void) #define SET_EBDA(var, val) \ SET_EBDA2(get_ebda_seg(), var, (val))
-#define EBDA_OFFSET_TOP_STACK \ - offsetof(struct extended_bios_data_area_s, extra_stack[ \ - FIELD_SIZEOF(struct extended_bios_data_area_s \ - , extra_stack)]) -
/**************************************************************** * Global variables @@ -321,6 +313,22 @@ static inline u16 get_global_seg(void) {
/**************************************************************** + * "Low" memory variables + ****************************************************************/ + +extern char _datalow_seg; +#define SEG_LOW ((u32)(&_datalow_seg)) + +#if MODESEGMENT +#define GET_LOW(var) GET_FARVAR(SEG_LOW, (var)) +#define SET_LOW(var, val) SET_FARVAR(SEG_LOW, (var), (val)) +#else +#define GET_LOW(var) (var) +#define SET_LOW(var, val) do { (var) = (val); } while (0) +#endif + + +/**************************************************************** * Bios Config Table ****************************************************************/
diff --git a/src/block.c b/src/block.c index a80199c..194d6f2 100644 --- a/src/block.c +++ b/src/block.c @@ -328,7 +328,7 @@ process_op(struct disk_op_s *op) } }
-// Execute a "disk_op_s" request - this runs on a stack in the ebda. +// Execute a "disk_op_s" request - this runs on the extra stack. static int __send_disk_op(struct disk_op_s *op_far, u16 op_seg) { @@ -349,7 +349,7 @@ __send_disk_op(struct disk_op_s *op_far, u16 op_seg) return status; }
-// Execute a "disk_op_s" request by jumping to a stack in the ebda. +// Execute a "disk_op_s" request by jumping to the extra 16bit stack. int send_disk_op(struct disk_op_s *op) { diff --git a/src/config.h b/src/config.h index 521469b..23591b9 100644 --- a/src/config.h +++ b/src/config.h @@ -39,6 +39,7 @@ #define BUILD_BIOS_ADDR 0xf0000 #define BUILD_BIOS_SIZE 0x10000 #define BUILD_LOWMEM_SIZE 0x8000 +#define BUILD_EXTRA_STACK_SIZE 0x800 // 32KB for shadow ram copying (works around emulator deficiencies) #define BUILD_BIOS_TMP_ADDR 0x30000 #define BUILD_SMM_INIT_ADDR 0x38000 diff --git a/src/post.c b/src/post.c index 8383b79..3561c0d 100644 --- a/src/post.c +++ b/src/post.c @@ -211,9 +211,6 @@ startBoot(void) static void maininit(void) { - // Running at new code address - do code relocation fixups - malloc_fixupreloc(); - // Setup ivt/bda/ebda init_ivt(); init_bda(); @@ -287,6 +284,21 @@ maininit(void) * POST entry and code relocation ****************************************************************/
+// Relocation fixup code that runs at new address after relocation complete. +static void +afterReloc(void *datalow) +{ + // Running at new code address - do code relocation fixups + malloc_fixupreloc(); + + // Move low-memory initial variable content to new location. + extern u8 datalow_start[], datalow_end[]; + memmove(datalow, datalow_start, datalow_end - datalow_start); + + // Run main code + maininit(); +} + // Update given relocs for the code at 'dest' with a given 'delta' static void updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta) @@ -311,27 +323,37 @@ reloc_init(void) extern u32 _reloc_rel_start[], _reloc_rel_end[]; extern u32 _reloc_init_start[], _reloc_init_end[]; extern u8 code32init_start[], code32init_end[]; + extern u32 _reloc_datalow_start[], _reloc_datalow_end[]; + extern u8 _datalow_min_align[]; + extern u8 datalow_start[], datalow_end[];
// Allocate space for init code. u32 initsize = code32init_end - code32init_start; - u32 align = (u32)&_reloc_min_align; - void *dest = memalign_tmp(align, initsize); - if (!dest) + u32 codealign = (u32)&_reloc_min_align; + void *codedest = memalign_tmp(codealign, initsize); + u32 datalowsize = datalow_end - datalow_start; + u32 datalowalign = (u32)&_datalow_min_align; + void *datalow = memalign_low(datalowalign, datalowsize); + if (!codedest || !datalow) panic("No space for init relocation.\n");
// Copy code and update relocs (init absolute, init relative, and runtime) + dprintf(1, "Relocating low data from %p to %p (size %d)\n" + , datalow_start, datalow, datalowsize); + updateRelocs(code32flat_start, _reloc_datalow_start, _reloc_datalow_end + , datalow - (void*)datalow_start); dprintf(1, "Relocating init from %p to %p (size %d)\n" - , code32init_start, dest, initsize); - s32 delta = dest - (void*)code32init_start; - memcpy(dest, code32init_start, initsize); - updateRelocs(dest, _reloc_abs_start, _reloc_abs_end, delta); - updateRelocs(dest, _reloc_rel_start, _reloc_rel_end, -delta); + , code32init_start, codedest, initsize); + s32 delta = codedest - (void*)code32init_start; + memcpy(codedest, code32init_start, initsize); + updateRelocs(codedest, _reloc_abs_start, _reloc_abs_end, delta); + updateRelocs(codedest, _reloc_rel_start, _reloc_rel_end, -delta); updateRelocs(code32flat_start, _reloc_init_start, _reloc_init_end, delta);
// Call maininit() in relocated code. - void (*func)(void) = (void*)maininit + delta; + void (*func)(void*) = (void*)afterReloc + delta; barrier(); - func(); + func(datalow); }
// Setup for code relocation and then call reloc_init diff --git a/src/romlayout.S b/src/romlayout.S index c4b2ef1..399f596 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -232,13 +232,11 @@ entry_resume: // Disable interrupts cli cld - // Use a stack in EBDA - movw $SEG_BDA, %ax - movw %ax, %ds - movw BDA_ebda_seg, %ax + // Use the ExtraStack in low mem. + movl $_datalow_seg, %eax movw %ax, %ds movw %ax, %ss - movl $EBDA_OFFSET_TOP_STACK, %esp + movl $ExtraStack + BUILD_EXTRA_STACK_SIZE, %esp // Call handler. jmp handle_resume
diff --git a/src/stacks.c b/src/stacks.c index 17f1a4a..26e633e 100644 --- a/src/stacks.c +++ b/src/stacks.c @@ -4,7 +4,7 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "biosvar.h" // get_ebda_seg +#include "biosvar.h" // GET_GLOBAL #include "util.h" // dprintf #include "bregs.h" // CR0_PE
@@ -149,21 +149,24 @@ wait_irq(void)
/**************************************************************** - * Stack in EBDA + * Extra 16bit stack ****************************************************************/
-// Switch to the extra stack in ebda and call a function. +// Space for a stack for 16bit code. +char ExtraStack[BUILD_EXTRA_STACK_SIZE] VARLOW __aligned(8); + +// Switch to the extra stack and call a function. inline u32 stack_hop(u32 eax, u32 edx, void *func) { ASSERT16(); - u16 ebda_seg = get_ebda_seg(), bkup_ss; + u16 stack_seg = SEG_LOW, bkup_ss; u32 bkup_esp; asm volatile( // Backup current %ss/%esp values. "movw %%ss, %w3\n" "movl %%esp, %4\n" - // Copy ebda seg to %ds/%ss and set %esp + // Copy stack seg to %ds/%ss and set %esp "movw %w6, %%ds\n" "movw %w6, %%ss\n" "movl %5, %%esp\n" @@ -174,7 +177,7 @@ stack_hop(u32 eax, u32 edx, void *func) "movw %w3, %%ss\n" "movl %4, %%esp" : "+a" (eax), "+d" (edx), "+c" (func), "=&r" (bkup_ss), "=&r" (bkup_esp) - : "i" (EBDA_OFFSET_TOP_STACK), "r" (ebda_seg) + : "i" (&ExtraStack[BUILD_EXTRA_STACK_SIZE]), "r" (stack_seg) : "cc", "memory"); return eax; } diff --git a/src/types.h b/src/types.h index c0c6d26..0f83697 100644 --- a/src/types.h +++ b/src/types.h @@ -61,6 +61,8 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; # define VAR32SEG __section(".discard.var32seg." UNIQSEC) // Designate a 32bit variable also available in 16bit "big real" mode. # define VAR32FLATVISIBLE __section(".discard.var32flat." UNIQSEC) __VISIBLE __weak +// Designate a variable as visible and located in the e-segment. +# define VARLOW __section(".discard.varlow." UNIQSEC) __VISIBLE __weak // Designate top-level assembler as 16bit only. # define ASM16(code) __ASM(code) // Designate top-level assembler as 32bit flat only. @@ -80,6 +82,7 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; # define VAR16FIXED(addr) VAR16VISIBLE # define VAR32SEG __section(".data32seg." UNIQSEC) # define VAR32FLATVISIBLE __section(".discard.var32flat." UNIQSEC) __VISIBLE __weak +# define VARLOW __section(".discard.varlow." UNIQSEC) __VISIBLE __weak # define ASM16(code) # define ASM32FLAT(code) # define ASSERT16() __force_link_error__only_in_16bit() @@ -96,6 +99,7 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; # define VAR16FIXED(addr) VAR16VISIBLE # define VAR32SEG __section(".discard.var32seg." UNIQSEC) # define VAR32FLATVISIBLE __section(".data.runtime." UNIQSEC) __VISIBLE +# define VARLOW __section(".datalow." UNIQSEC) __VISIBLE # define ASM16(code) # define ASM32FLAT(code) __ASM(code) # define ASSERT16() __force_link_error__only_in_16bit() diff --git a/src/util.h b/src/util.h index 04de66b..0c731fe 100644 --- a/src/util.h +++ b/src/util.h @@ -230,6 +230,7 @@ int get_keystroke(int msec);
// stacks.c u32 call32(void *func, u32 eax, u32 errret); +extern char ExtraStack[]; inline u32 stack_hop(u32 eax, u32 edx, void *func); extern struct thread_info MainThread; extern int CanPreempt; diff --git a/tools/layoutrom.py b/tools/layoutrom.py index 86e1f33..4ce8cce 100755 --- a/tools/layoutrom.py +++ b/tools/layoutrom.py @@ -40,7 +40,7 @@ def alignpos(pos, alignbytes):
# Determine the final addresses for a list of sections that end at an # address. -def setSectionsStart(sections, endaddr, minalign=1): +def setSectionsStart(sections, endaddr, minalign=1, segoffset=0): totspace = 0 for section in sections: if section.align > minalign: @@ -53,8 +53,9 @@ def setSectionsStart(sections, endaddr, minalign=1): for section in sections: curaddr = alignpos(curaddr, section.align) section.finalloc = curaddr + section.finalsegloc = curaddr - segoffset curaddr += section.size - return startaddr + return startaddr, minalign
# The 16bit code can't exceed 64K of space. BUILD_BIOS_ADDR = 0xf0000 @@ -69,7 +70,8 @@ def fitSections(sections, fillsections): for section in sections: if section.name.startswith('.fixedaddr.'): addr = int(section.name[11:], 16) - section.finalloc = addr + section.finalloc = addr + BUILD_BIOS_ADDR + section.finalsegloc = addr fixedsections.append((addr, section)) if section.align != 1: print "Error: Fixed section %s has non-zero alignment (%d)" % ( @@ -99,7 +101,7 @@ def fitSections(sections, fillsections): canrelocate = [section for size, align, name, section in canrelocate] totalused = 0 for freespace, fixedsection in fixedAddr: - addpos = fixedsection.finalloc + fixedsection.size + addpos = fixedsection.finalsegloc + fixedsection.size totalused += fixedsection.size nextfixedaddr = addpos + freespace # print "Filling section %x uses %d, next=%x, available=%d" % ( @@ -122,7 +124,8 @@ def fitSections(sections, fillsections): # Found a section that can fit. fitnextaddr, fitsection = canfit canrelocate.remove(fitsection) - fitsection.finalloc = addpos + fitsection.finalloc = addpos + BUILD_BIOS_ADDR + fitsection.finalsegloc = addpos addpos = fitnextaddr totalused += fitsection.size # print " Adding %s (size %d align %d) pos=%x avail=%d" % ( @@ -137,68 +140,104 @@ def fitSections(sections, fillsections): firstfixed, BUILD_BIOS_SIZE, total, slack, (float(slack) / total) * 100.0))
- return firstfixed + return firstfixed + BUILD_BIOS_ADDR + +# Return the subset of sections with a given category +def getSectionsCategory(sections, category): + return [section for section in sections if section.category == category]
# Return the subset of sections with a given name prefix -def getSectionsPrefix(sections, category, prefix): +def getSectionsPrefix(sections, prefix): return [section for section in sections - if section.category == category and section.name.startswith(prefix)] - -def doLayout(sections): + if section.name.startswith(prefix)] + +# The sections (and associated information) to be placed in output rom +class LayoutInfo: + sections16 = sec16_start = sec16_align = None + sections32seg = sec32seg_start = sec32seg_align = None + sections32flat = sec32flat_start = sec32flat_align = None + sections32init = sec32init_start = sec32init_align = None + sections32low = sec32low_start = sec32low_align = None + sec32low_base = None + +# Determine final memory addresses for sections +def doLayout(sections, genreloc): + li = LayoutInfo() # Determine 16bit positions - textsections = getSectionsPrefix(sections, '16', '.text.') + li.sections16 = getSectionsCategory(sections, '16') + textsections = getSectionsPrefix(li.sections16, '.text.') rodatasections = ( - getSectionsPrefix(sections, '16', '.rodata.str1.1') - + getSectionsPrefix(sections, '16', '.rodata.__func__.') - + getSectionsPrefix(sections, '16', '.rodata.__PRETTY_FUNCTION__.')) - datasections = getSectionsPrefix(sections, '16', '.data16.') - fixedsections = getSectionsPrefix(sections, '16', '.fixedaddr.') + getSectionsPrefix(li.sections16, '.rodata.str1.1') + + getSectionsPrefix(li.sections16, '.rodata.__func__.') + + getSectionsPrefix(li.sections16, '.rodata.__PRETTY_FUNCTION__.')) + datasections = getSectionsPrefix(li.sections16, '.data16.') + fixedsections = getSectionsPrefix(li.sections16, '.fixedaddr.')
firstfixed = fitSections(fixedsections, textsections) remsections = [s for s in textsections+rodatasections+datasections if s.finalloc is None] - code16_start = setSectionsStart(remsections, firstfixed) + li.sec16_start, li.sec16_align = setSectionsStart( + remsections, firstfixed, segoffset=BUILD_BIOS_ADDR)
# Determine 32seg positions - textsections = getSectionsPrefix(sections, '32seg', '.text.') + li.sections32seg = getSectionsCategory(sections, '32seg') + textsections = getSectionsPrefix(li.sections32seg, '.text.') rodatasections = ( - getSectionsPrefix(sections, '32seg', '.rodata.str1.1') - + getSectionsPrefix(sections, '32seg', '.rodata.__func__.') - + getSectionsPrefix(sections, '32seg', '.rodata.__PRETTY_FUNCTION__.')) - datasections = getSectionsPrefix(sections, '32seg', '.data32seg.') + getSectionsPrefix(li.sections32seg, '.rodata.str1.1') + + getSectionsPrefix(li.sections32seg, '.rodata.__func__.') + + getSectionsPrefix(li.sections32seg, '.rodata.__PRETTY_FUNCTION__.')) + datasections = getSectionsPrefix(li.sections32seg, '.data32seg.')
- code32seg_start = setSectionsStart( - textsections + rodatasections + datasections, code16_start) + li.sec32seg_start, li.sec32seg_align = setSectionsStart( + textsections + rodatasections + datasections, li.sec16_start + , segoffset=BUILD_BIOS_ADDR)
# Determine 32flat runtime positions - textsections = getSectionsPrefix(sections, '32flat', '.text.') - rodatasections = getSectionsPrefix(sections, '32flat', '.rodata') - datasections = getSectionsPrefix(sections, '32flat', '.data.') - bsssections = getSectionsPrefix(sections, '32flat', '.bss.') + li.sections32flat = getSectionsCategory(sections, '32flat') + textsections = getSectionsPrefix(li.sections32flat, '.text.') + rodatasections = getSectionsPrefix(li.sections32flat, '.rodata') + datasections = getSectionsPrefix(li.sections32flat, '.data.') + bsssections = getSectionsPrefix(li.sections32flat, '.bss.')
- code32flat_start = setSectionsStart( + li.sec32flat_start, li.sec32flat_align = setSectionsStart( textsections + rodatasections + datasections + bsssections - , code32seg_start + BUILD_BIOS_ADDR, 16) + , li.sec32seg_start, 16)
# Determine 32flat init positions - textsections = getSectionsPrefix(sections, '32init', '.text.') - rodatasections = getSectionsPrefix(sections, '32init', '.rodata') - datasections = getSectionsPrefix(sections, '32init', '.data.') - bsssections = getSectionsPrefix(sections, '32init', '.bss.') + li.sections32init = getSectionsCategory(sections, '32init') + textsections = getSectionsPrefix(li.sections32init, '.text.') + rodatasections = getSectionsPrefix(li.sections32init, '.rodata') + datasections = getSectionsPrefix(li.sections32init, '.data.') + bsssections = getSectionsPrefix(li.sections32init, '.bss.')
- code32init_start = setSectionsStart( + li.sec32init_start, li.sec32init_align = setSectionsStart( textsections + rodatasections + datasections + bsssections - , code32flat_start, 16) + , li.sec32flat_start, 16) + + # Determine "low memory" data positions + li.sections32low = getSectionsCategory(sections, '32low') + if genreloc: + sec32low_top = li.sec32init_start + seg32low_base = min(BUILD_BIOS_ADDR, li.sec32flat_start) - 64*1024 + 16 + else: + sec32low_top = min(li.sec32init_start, BUILD_BIOS_ADDR) + seg32low_base = sec32low_top - 64*1024 + 16 + li.seg32low_base = alignpos(seg32low_base, 2*1024) + li.sec32low_start, li.sec32low_align = setSectionsStart( + li.sections32low, sec32low_top, 16, segoffset=li.seg32low_base)
# Print statistics - size16 = BUILD_BIOS_SIZE - code16_start - size32seg = code16_start - code32seg_start - size32flat = code32seg_start + BUILD_BIOS_ADDR - code32flat_start - size32init = code32flat_start - code32init_start + size16 = BUILD_BIOS_ADDR + BUILD_BIOS_SIZE - li.sec16_start + size32seg = li.sec16_start - li.sec32seg_start + size32flat = li.sec32seg_start - li.sec32flat_start + size32init = li.sec32flat_start - li.sec32init_start + sizelow = sec32low_top - li.sec32low_start print "16bit size: %d" % size16 print "32bit segmented size: %d" % size32seg print "32bit flat size: %d" % size32flat print "32bit flat init size: %d" % size32init + print "lowmem size: %d" % sizelow + return li
###################################################################### @@ -206,7 +245,7 @@ def doLayout(sections): ######################################################################
# Write LD script includes for the given cross references -def outXRefs(sections): +def outXRefs(sections, useseg=0): xrefs = {} out = "" for section in sections: @@ -218,162 +257,155 @@ def outXRefs(sections): or reloc.symbolname in xrefs): continue xrefs[reloc.symbolname] = 1 - addr = symbol.section.finalloc + symbol.offset - if (section.fileid == '32flat' - and symbol.section.fileid in ('16', '32seg')): - addr += BUILD_BIOS_ADDR - out += "%s = 0x%x ;\n" % (reloc.symbolname, addr) + loc = symbol.section.finalloc + if useseg: + loc = symbol.section.finalsegloc + out += "%s = 0x%x ;\n" % (reloc.symbolname, loc + symbol.offset) return out
# Write LD script includes for the given sections using relative offsets -def outRelSections(sections, startsym): +def outRelSections(sections, startsym, useseg=0): + sections = [(section.finalloc, section) for section in sections + if section.finalloc is not None] + sections.sort() out = "" - for section in sections: - out += ". = ( 0x%x - %s ) ;\n" % (section.finalloc, startsym) + for addr, section in sections: + loc = section.finalloc + if useseg: + loc = section.finalsegloc + out += ". = ( 0x%x - %s ) ;\n" % (loc, startsym) if section.name == '.rodata.str1.1': out += "_rodata = . ;\n" out += "*(%s)\n" % (section.name,) return out
-def getSectionsFile(sections, fileid, defaddr=0): - sections = [(section.finalloc, section) - for section in sections if section.fileid == fileid] - sections.sort() - sections = [section for addr, section in sections] - pos = defaddr - if sections: - pos = sections[0].finalloc - return sections, pos - -# Layout the 32bit segmented code. This places the code as high as possible. -def writeLinkerScripts(sections, entrysym, genreloc, out16, out32seg, out32flat): +# Build linker script output for a list of relocations. +def strRelocs(outname, outrel, relocs): + relocs.sort() + return (" %s_start = ABSOLUTE(.) ;\n" % (outname,) + + "".join(["LONG(0x%x - %s)\n" % (pos, outrel) + for pos in relocs]) + + " %s_end = ABSOLUTE(.) ;\n" % (outname,)) + +# Find all relocations in the given sections with the given attributes +def getRelocs(sections, type=None, category=None, notcategory=None): + out = [] + for section in sections: + for reloc in section.relocs: + if reloc.symbol.section is None: + continue + destcategory = reloc.symbol.section.category + if ((type is None or reloc.type == type) + and (category is None or destcategory == category) + and (notcategory is None or destcategory != notcategory)): + out.append(section.finalloc + reloc.offset) + return out + +# Return the start address and minimum alignment for a set of sections +def getSectionsStart(sections, defaddr=0): + return min([section.finalloc for section in sections + if section.finalloc is not None] or [defaddr]) + +# Output the linker scripts for all required sections. +def writeLinkerScripts(li, entrysym, genreloc, out16, out32seg, out32flat): # Write 16bit linker script - sections16, code16_start = getSectionsFile(sections, '16') - output = open(out16, 'wb') - output.write(COMMONHEADER + outXRefs(sections16) + """ + out = outXRefs(li.sections16, useseg=1) + """ + _datalow_base = 0x%x ; + _datalow_seg = 0x%x ; + code16_start = 0x%x ; .text16 code16_start : { -""" % (code16_start) - + outRelSections(sections16, 'code16_start') - + """ +%s } -""" - + COMMONTRAILER) - output.close() +""" % (li.seg32low_base, + li.seg32low_base / 16, + li.sec16_start - BUILD_BIOS_ADDR, + outRelSections(li.sections16, 'code16_start', useseg=1)) + outfile = open(out16, 'wb') + outfile.write(COMMONHEADER + out + COMMONTRAILER) + outfile.close()
# Write 32seg linker script - sections32seg, code32seg_start = getSectionsFile( - sections, '32seg', code16_start) - output = open(out32seg, 'wb') - output.write(COMMONHEADER + outXRefs(sections32seg) + """ + out = outXRefs(li.sections32seg, useseg=1) + """ code32seg_start = 0x%x ; .text32seg code32seg_start : { -""" % (code32seg_start) - + outRelSections(sections32seg, 'code32seg_start') - + """ +%s } -""" - + COMMONTRAILER) - output.close() +""" % (li.sec32seg_start - BUILD_BIOS_ADDR, + outRelSections(li.sections32seg, 'code32seg_start', useseg=1)) + outfile = open(out32seg, 'wb') + outfile.write(COMMONHEADER + out + COMMONTRAILER) + outfile.close()
# Write 32flat linker script - sections32flat, code32flat_start = getSectionsFile( - sections, '32flat', code32seg_start) + sections32all = li.sections32flat + li.sections32init + li.sections32low + sec32all_start = li.sec32low_start + entrysympos = entrysym.section.finalloc + entrysym.offset relocstr = "" - relocminalign = 0 if genreloc: # Generate relocations - relocstr, size, relocminalign = genRelocs(sections) - code32flat_start -= size - output = open(out32flat, 'wb') - output.write(COMMONHEADER - + outXRefs(sections32flat) + """ + absrelocs = getRelocs( + li.sections32init, type='R_386_32', category='32init') + relrelocs = getRelocs( + li.sections32init, type='R_386_PC32', notcategory='32init') + initrelocs = getRelocs( + li.sections32flat + li.sections32low + li.sections16 + + li.sections32seg, category='32init') + lowrelocs = getRelocs( + li.sections16 + li.sections32seg + sections32all, category='32low') + relocstr = (strRelocs("_reloc_abs", "code32init_start", absrelocs) + + strRelocs("_reloc_rel", "code32init_start", relrelocs) + + strRelocs("_reloc_init", "code32flat_start", initrelocs) + + strRelocs("_reloc_datalow", "code32flat_start", lowrelocs)) + numrelocs = len(absrelocs + relrelocs + initrelocs + lowrelocs) + sec32all_start -= numrelocs * 4 + out = outXRefs(sections32all) + """ %s = 0x%x ; _reloc_min_align = 0x%x ; + _datalow_min_align = 0x%x ; + code32flat_start = 0x%x ; .text code32flat_start : { -""" % (entrysym.name, - entrysym.section.finalloc + entrysym.offset + BUILD_BIOS_ADDR, - relocminalign, code32flat_start) - + relocstr - + """ +%s + datalow_start = ABSOLUTE(.) ; +%s + datalow_end = ABSOLUTE(.) ; code32init_start = ABSOLUTE(.) ; -""" - + outRelSections(getSectionsPrefix(sections32flat, '32init', '') - , 'code32flat_start') - + """ +%s code32init_end = ABSOLUTE(.) ; -""" - + outRelSections(getSectionsPrefix(sections32flat, '32flat', '') - , 'code32flat_start') - + """ +%s . = ( 0x%x - code32flat_start ) ; *(.text32seg) . = ( 0x%x - code32flat_start ) ; *(.text16) code32flat_end = ABSOLUTE(.) ; } :text -""" % (code32seg_start + BUILD_BIOS_ADDR, code16_start + BUILD_BIOS_ADDR) - + COMMONTRAILER - + """ +""" % (entrysym.name, entrysympos, + li.sec32init_align, + li.sec32low_align, + sec32all_start, + relocstr, + outRelSections(li.sections32low, 'code32flat_start'), + outRelSections(li.sections32init, 'code32flat_start'), + outRelSections(li.sections32flat, 'code32flat_start'), + li.sec32seg_start, + li.sec16_start) + out = COMMONHEADER + out + COMMONTRAILER + """ ENTRY(%s) PHDRS { text PT_LOAD AT ( code32flat_start ) ; } -""" % (entrysym.name,)) - output.close() +""" % (entrysym.name,) + outfile = open(out32flat, 'wb') + outfile.write(out) + outfile.close()
###################################################################### # Detection of init code ######################################################################
-# Determine init section relocations -def genRelocs(sections): - absrelocs = [] - relrelocs = [] - initrelocs = [] - minalign = 16 - for section in sections: - if section.category == '32init' and section.align > minalign: - minalign = section.align - for reloc in section.relocs: - symbol = reloc.symbol - if symbol.section is None: - continue - relocpos = section.finalloc + reloc.offset - if (reloc.type == 'R_386_32' and section.category == '32init' - and symbol.section.category == '32init'): - # Absolute relocation - absrelocs.append(relocpos) - elif (reloc.type == 'R_386_PC32' and section.category == '32init' - and symbol.section.category != '32init'): - # Relative relocation - relrelocs.append(relocpos) - elif (section.category != '32init' - and symbol.section.category == '32init'): - # Relocation to the init section - if section.fileid in ('16', '32seg'): - relocpos += BUILD_BIOS_ADDR - initrelocs.append(relocpos) - absrelocs.sort() - relrelocs.sort() - initrelocs.sort() - out = (" _reloc_abs_start = ABSOLUTE(.) ;\n" - + "".join(["LONG(0x%x - code32init_start)\n" % (pos,) - for pos in absrelocs]) - + " _reloc_abs_end = ABSOLUTE(.) ;\n" - + " _reloc_rel_start = ABSOLUTE(.) ;\n" - + "".join(["LONG(0x%x - code32init_start)\n" % (pos,) - for pos in relrelocs]) - + " _reloc_rel_end = ABSOLUTE(.) ;\n" - + " _reloc_init_start = ABSOLUTE(.) ;\n" - + "".join(["LONG(0x%x - code32flat_start)\n" % (pos,) - for pos in initrelocs]) - + " _reloc_init_end = ABSOLUTE(.) ;\n") - return out, len(absrelocs + relrelocs + initrelocs) * 4, minalign - def markRuntime(section, sections): if (section is None or not section.keep or section.category is not None or '.init.' in section.name or section.fileid != '32flat'): @@ -386,7 +418,8 @@ def markRuntime(section, sections): def findInit(sections): # Recursively find and mark all "runtime" sections. for section in sections: - if '.runtime.' in section.name or '.export.' in section.name: + if ('.datalow.' in section.name or '.runtime.' in section.name + or '.export.' in section.name): markRuntime(section, sections) for section in sections: if section.category is not None: @@ -468,7 +501,7 @@ def gc(info16, info32seg, info32flat):
class Section: name = size = alignment = fileid = relocs = None - finalloc = category = keep = None + finalloc = finalsegloc = category = keep = None class Reloc: offset = type = symbolname = symbol = None class Symbol: @@ -571,13 +604,17 @@ def main(): # Separate 32bit flat into runtime and init parts findInit(sections)
+ # Note "low memory" parts + for section in getSectionsPrefix(sections, '.datalow.'): + section.category = '32low' + # Determine the final memory locations of each kept section. - doLayout(sections) + genreloc = '_reloc_abs_start' in info32flat[1] + li = doLayout(sections, genreloc)
# Write out linker script files. entrysym = info16[1]['entry_elf'] - genreloc = '_reloc_abs_start' in info32flat[1] - writeLinkerScripts(sections, entrysym, genreloc, out16, out32seg, out32flat) + writeLinkerScripts(li, entrysym, genreloc, out16, out32seg, out32flat)
if __name__ == '__main__': main()
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/biosvar.h | 6 ------ src/clock.c | 32 +++++++++++++++++--------------- 2 files changed, 17 insertions(+), 21 deletions(-)
diff --git a/src/biosvar.h b/src/biosvar.h index 88b3257..45561d9 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -226,8 +226,6 @@ struct extended_bios_data_area_s { u8 ps2ctr; struct usbkeyinfo usbkey_last;
- int RTCusers; - // El Torito Emulation data struct cdemu_s cdemu;
@@ -238,10 +236,6 @@ struct extended_bios_data_area_s { u8 cdrom_locks[CONFIG_MAX_EXTDRIVE];
u16 boot_sequence; - - /* TSC emulation timekeepers */ - u64 tsc_8254; - int last_tsc_8254; } PACKED;
// The initial size and location of EBDA diff --git a/src/clock.c b/src/clock.c index e8a48a1..c66c3f0 100644 --- a/src/clock.c +++ b/src/clock.c @@ -108,22 +108,24 @@ calibrate_tsc(void) dprintf(1, "CPU Mhz=%u\n", hz / 1000000); }
+/* TSC emulation timekeepers */ +u64 TSC_8254 VARLOW; +int Last_TSC_8254 VARLOW; + static u64 emulate_tsc(void) { - int cnt, d; - u16 ebda_seg = get_ebda_seg(); - u64 ret; /* read timer 0 current count */ - ret = GET_EBDA2(ebda_seg, tsc_8254); - /* readback mode has slightly shifted registers, works on all 8254, readback PIT0 latch */ + u64 ret = GET_LOW(TSC_8254); + /* readback mode has slightly shifted registers, works on all + * 8254, readback PIT0 latch */ outb(PM_SEL_READBACK | PM_READ_VALUE | PM_READ_COUNTER0, PORT_PIT_MODE); - cnt = (inb(PORT_PIT_COUNTER0) | (inb(PORT_PIT_COUNTER0) << 8)); - d = GET_EBDA2(ebda_seg, last_tsc_8254) - cnt; + int cnt = (inb(PORT_PIT_COUNTER0) | (inb(PORT_PIT_COUNTER0) << 8)); + int d = GET_LOW(Last_TSC_8254) - cnt; /* Determine the ticks count from last invocation of this function */ ret += (d > 0) ? d : (PIT_TICK_INTERVAL + d); - SET_EBDA2(ebda_seg, last_tsc_8254, cnt); - SET_EBDA2(ebda_seg, tsc_8254, ret); + SET_LOW(Last_TSC_8254, cnt); + SET_LOW(TSC_8254, ret); return ret; }
@@ -545,12 +547,13 @@ handle_08(void) * Periodic timer ****************************************************************/
+int RTCusers VARLOW; + void useRTC(void) { - u16 ebda_seg = get_ebda_seg(); - int count = GET_EBDA2(ebda_seg, RTCusers); - SET_EBDA2(ebda_seg, RTCusers, count+1); + int count = GET_LOW(RTCusers); + SET_LOW(RTCusers, count+1); if (count) return; // Turn on the Periodic Interrupt timer @@ -561,9 +564,8 @@ useRTC(void) void releaseRTC(void) { - u16 ebda_seg = get_ebda_seg(); - int count = GET_EBDA2(ebda_seg, RTCusers); - SET_EBDA2(ebda_seg, RTCusers, count-1); + int count = GET_LOW(RTCusers); + SET_LOW(RTCusers, count-1); if (count != 1) return; // Clear the Periodic Interrupt.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/biosvar.h | 2 -- src/boot.c | 13 ++++++------- 2 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/src/biosvar.h b/src/biosvar.h index 45561d9..2458308 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -234,8 +234,6 @@ struct extended_bios_data_area_s {
// Locks for removable devices u8 cdrom_locks[CONFIG_MAX_EXTDRIVE]; - - u16 boot_sequence; } PACKED;
// The initial size and location of EBDA diff --git a/src/boot.c b/src/boot.c index 4447b9a..ef21fe4 100644 --- a/src/boot.c +++ b/src/boot.c @@ -238,8 +238,6 @@ boot_setup(void) if (! CONFIG_BOOT) return;
- SET_EBDA(boot_sequence, 0xffff); - if (!CONFIG_COREBOOT) { // On emulators, get boot order from nvram. if (inb_cmos(CMOS_BIOS_BOOTFLAG1) & 1) @@ -642,7 +640,7 @@ boot_fail(void)
// Determine next boot method and attempt a boot using it. static void -do_boot(u16 seq_nr) +do_boot(int seq_nr) { if (! CONFIG_BOOT) panic("Boot support not compiled in.\n"); @@ -679,15 +677,16 @@ do_boot(u16 seq_nr) call16_int(0x18, &br); }
+int BootSequence VARLOW = -1; + // Boot Failure recovery: try the next device. void VISIBLE32FLAT handle_18(void) { debug_serial_setup(); debug_enter(NULL, DEBUG_HDL_18); - u16 ebda_seg = get_ebda_seg(); - u16 seq = GET_EBDA2(ebda_seg, boot_sequence) + 1; - SET_EBDA2(ebda_seg, boot_sequence, seq); + int seq = BootSequence + 1; + BootSequence = seq; do_boot(seq); }
@@ -697,6 +696,6 @@ handle_19(void) { debug_serial_setup(); debug_enter(NULL, DEBUG_HDL_19); - SET_EBDA(boot_sequence, 0); + BootSequence = 0; do_boot(0); }
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/biosvar.h | 1 - src/ps2port.c | 19 ++++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/biosvar.h b/src/biosvar.h index 2458308..c19bc85 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -223,7 +223,6 @@ struct extended_bios_data_area_s { u8 other2[0xC4];
// 0x121 - Begin custom storage. - u8 ps2ctr; struct usbkeyinfo usbkey_last;
// El Torito Emulation data diff --git a/src/ps2port.c b/src/ps2port.c index 4b27b7a..15bce8e 100644 --- a/src/ps2port.c +++ b/src/ps2port.c @@ -8,7 +8,7 @@ #include "ioport.h" // inb #include "util.h" // dprintf #include "paravirt.h" // romfile_loadint -#include "biosvar.h" // GET_EBDA +#include "biosvar.h" // GET_LOW #include "ps2port.h" // ps2_kbd_command #include "pic.h" // eoi_pic1
@@ -208,6 +208,8 @@ ps2_sendbyte(int aux, u8 command, int timeout) return 0; }
+u8 Ps2ctr VARLOW; + static int __ps2_command(int aux, int command, u8 *param) { @@ -216,7 +218,7 @@ __ps2_command(int aux, int command, u8 *param) int send = (command >> 12) & 0xf;
// Disable interrupts and keyboard/mouse. - u8 ps2ctr = GET_EBDA(ps2ctr); + u8 ps2ctr = GET_LOW(Ps2ctr); u8 newctr = ((ps2ctr | I8042_CTR_AUXDIS | I8042_CTR_KBDDIS) & ~(I8042_CTR_KBDINT|I8042_CTR_AUXINT)); dprintf(6, "i8042 ctr old=%x new=%x\n", ps2ctr, newctr); @@ -337,13 +339,12 @@ ps2_mouse_command(int command, u8 *param)
// Update ps2ctr for mouse enable/disable. if (command == PSMOUSE_CMD_ENABLE || command == PSMOUSE_CMD_DISABLE) { - u16 ebda_seg = get_ebda_seg(); - u8 ps2ctr = GET_EBDA2(ebda_seg, ps2ctr); + u8 ps2ctr = GET_LOW(Ps2ctr); if (command == PSMOUSE_CMD_ENABLE) ps2ctr = (ps2ctr | I8042_CTR_AUXINT) & ~I8042_CTR_AUXDIS; else ps2ctr = (ps2ctr | I8042_CTR_AUXDIS) & ~I8042_CTR_AUXINT; - SET_EBDA2(ebda_seg, ps2ctr, ps2ctr); + SET_LOW(Ps2ctr, ps2ctr); }
return ps2_command(1, command, param); @@ -371,7 +372,7 @@ handle_74(void) } v = inb(PORT_PS2_DATA);
- if (!(GET_EBDA(ps2ctr) & I8042_CTR_AUXINT)) + if (!(GET_LOW(Ps2ctr) & I8042_CTR_AUXINT)) // Interrupts not enabled. goto done;
@@ -398,7 +399,7 @@ handle_09(void) } v = inb(PORT_PS2_DATA);
- if (!(GET_EBDA(ps2ctr) & I8042_CTR_KBDINT)) + if (!(GET_LOW(Ps2ctr) & I8042_CTR_KBDINT)) // Interrupts not enabled. goto done;
@@ -444,7 +445,7 @@ keyboard_init(void *data) }
// Disable keyboard and mouse events. - SET_EBDA(ps2ctr, I8042_CTR_KBDDIS | I8042_CTR_AUXDIS); + SET_LOW(Ps2ctr, I8042_CTR_KBDDIS | I8042_CTR_AUXDIS);
/* ------------------- keyboard side ------------------------*/ @@ -479,7 +480,7 @@ keyboard_init(void *data) return;
// Keyboard Mode: disable mouse, scan code convert, enable kbd IRQ - SET_EBDA(ps2ctr, I8042_CTR_AUXDIS | I8042_CTR_XLATE | I8042_CTR_KBDINT); + SET_LOW(Ps2ctr, I8042_CTR_AUXDIS | I8042_CTR_XLATE | I8042_CTR_KBDINT);
/* Enable keyboard */ ret = ps2_kbd_command(ATKBD_CMD_ENABLE, NULL);
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/biosvar.h | 12 ------------ src/usb-hid.c | 17 ++++++++++++++--- 2 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/src/biosvar.h b/src/biosvar.h index c19bc85..6521acf 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -195,17 +195,6 @@ struct fdpt_s { u8 checksum; } PACKED;
-struct usbkeyinfo { - union { - struct { - u8 modifiers; - u8 repeatcount; - u8 keys[6]; - }; - u64 data; - }; -}; - struct extended_bios_data_area_s { u8 size; u8 reserved1[0x21]; @@ -223,7 +212,6 @@ struct extended_bios_data_area_s { u8 other2[0xC4];
// 0x121 - Begin custom storage. - struct usbkeyinfo usbkey_last;
// El Torito Emulation data struct cdemu_s cdemu; diff --git a/src/usb-hid.c b/src/usb-hid.c index 6e8ec4e..a4fe4ae 100644 --- a/src/usb-hid.c +++ b/src/usb-hid.c @@ -211,6 +211,18 @@ procmodkey(u8 mods, u8 flags) } }
+struct usbkeyinfo { + union { + struct { + u8 modifiers; + u8 repeatcount; + u8 keys[6]; + }; + u64 data; + }; +}; +struct usbkeyinfo LastUSBkey VARLOW; + // Process USB keyboard data. static void noinline handle_key(struct keyevent *data) @@ -218,9 +230,8 @@ handle_key(struct keyevent *data) dprintf(9, "Got key %x %x\n", data->modifiers, data->keys[0]);
// Load old keys. - u16 ebda_seg = get_ebda_seg(); struct usbkeyinfo old; - old.data = GET_EBDA2(ebda_seg, usbkey_last.data); + old.data = GET_LOW(LastUSBkey.data);
// Check for keys no longer pressed. int addpos = 0; @@ -273,7 +284,7 @@ handle_key(struct keyevent *data) }
// Update old keys - SET_EBDA2(ebda_seg, usbkey_last.data, old.data); + SET_LOW(LastUSBkey.data, old.data); }
// Check if a USB keyboard event is pending and process it if so.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/biosvar.h | 43 +---------------------------- src/block.c | 1 + src/blockcmd.h | 2 + src/boot.c | 6 +-- src/cdrom.c | 84 ++++++++++++++++++++++++++++---------------------------- src/coreboot.c | 3 +- src/disk.c | 75 +++++++++++++++++++++---------------------------- src/disk.h | 38 ++++++++++++++++++++++++- 8 files changed, 118 insertions(+), 134 deletions(-)
diff --git a/src/biosvar.h b/src/biosvar.h index 6521acf..4d62df1 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -8,8 +8,7 @@
#include "types.h" // u8 #include "farptr.h" // GET_FARVAR -#include "config.h" // CONFIG_* -#include "disk.h" // struct chs_s +#include "config.h" // SEG_BDA
/**************************************************************** @@ -149,37 +148,6 @@ struct bios_data_area_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; -}; - -// ElTorito Device Emulation data -struct cdemu_s { - struct drive_s *emulated_drive_gf; - u32 ilba; - u16 buffer_segment; - u16 load_segment; - u16 sector_count; - u8 active; - u8 media; - u8 emulated_extdrive; - - // Virtual device - struct chs_s lchs; -}; - struct fdpt_s { u16 cylinders; u8 heads; @@ -212,15 +180,6 @@ struct extended_bios_data_area_s { u8 other2[0xC4];
// 0x121 - Begin custom storage. - - // El Torito Emulation data - struct cdemu_s cdemu; - - // Buffer for disk DPTE table - struct dpte_s dpte; - - // Locks for removable devices - u8 cdrom_locks[CONFIG_MAX_EXTDRIVE]; } PACKED;
// The initial size and location of EBDA diff --git a/src/block.c b/src/block.c index 194d6f2..44ba9bd 100644 --- a/src/block.c +++ b/src/block.c @@ -18,6 +18,7 @@ u8 FloppyCount VAR16VISIBLE; u8 CDCount; struct drive_s *IDMap[3][CONFIG_MAX_EXTDRIVE] VAR16VISIBLE; u8 *bounce_buf_fl VAR16VISIBLE; +struct dpte_s DefaultDPTE VARLOW;
struct drive_s * getDrive(u8 exttype, u8 extdriveoffset) diff --git a/src/blockcmd.h b/src/blockcmd.h index 8459d3e..b45bbb7 100644 --- a/src/blockcmd.h +++ b/src/blockcmd.h @@ -101,6 +101,7 @@ struct cdbres_mode_sense_geom {
// blockcmd.c int cdb_is_read(u8 *cdbcmd, u16 blocksize); +struct disk_op_s; int cdb_get_inquiry(struct disk_op_s *op, struct cdbres_inquiry *data); int cdb_get_sense(struct disk_op_s *op, struct cdbres_request_sense *data); int cdb_test_unit_ready(struct disk_op_s *op); @@ -111,6 +112,7 @@ int cdb_read(struct disk_op_s *op); int cdb_write(struct disk_op_s *op);
int scsi_is_ready(struct disk_op_s *op); +struct drive_s; int scsi_init_drive(struct drive_s *drive, const char *s, int prio);
#endif // blockcmd.h diff --git a/src/boot.c b/src/boot.c index ef21fe4..7676eb7 100644 --- a/src/boot.c +++ b/src/boot.c @@ -6,7 +6,6 @@ // This file may be distributed under the terms of the GNU LGPLv3 license.
#include "util.h" // dprintf -#include "biosvar.h" // GET_EBDA #include "config.h" // CONFIG_* #include "disk.h" // cdrom_boot #include "bregs.h" // struct bregs @@ -585,9 +584,8 @@ boot_cdrom(struct drive_s *drive_g) return; }
- u16 ebda_seg = get_ebda_seg(); - u8 bootdrv = GET_EBDA2(ebda_seg, cdemu.emulated_extdrive); - u16 bootseg = GET_EBDA2(ebda_seg, cdemu.load_segment); + u8 bootdrv = CDEmu.emulated_extdrive; + u16 bootseg = CDEmu.load_segment; /* Canonicalize bootseg:bootip */ u16 bootip = (bootseg & 0x0fff) << 4; bootseg &= 0xf000; diff --git a/src/cdrom.c b/src/cdrom.c index 170ffc4..f3208b5 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -8,27 +8,30 @@ #include "disk.h" // cdrom_13 #include "util.h" // memset #include "bregs.h" // struct bregs -#include "biosvar.h" // GET_EBDA +#include "biosvar.h" // GET_GLOBAL #include "ata.h" // ATA_CMD_REQUEST_SENSE #include "blockcmd.h" // CDB_CMD_REQUEST_SENSE
+// Locks for removable devices +u8 CDRom_locks[CONFIG_MAX_EXTDRIVE] VARLOW; +
/**************************************************************** * CD emulation ****************************************************************/
+struct cdemu_s CDEmu VARLOW; struct drive_s *cdemu_drive_gf VAR16VISIBLE;
static int cdemu_read(struct disk_op_s *op) { - u16 ebda_seg = get_ebda_seg(); struct drive_s *drive_g; - drive_g = GLOBALFLAT2GLOBAL(GET_EBDA2(ebda_seg, cdemu.emulated_drive_gf)); + drive_g = GLOBALFLAT2GLOBAL(GET_LOW(CDEmu.emulated_drive_gf)); struct disk_op_s dop; dop.drive_g = drive_g; dop.command = op->command; - dop.lba = GET_EBDA2(ebda_seg, cdemu.ilba) + op->lba / 4; + dop.lba = GET_LOW(CDEmu.ilba) + op->lba / 4;
int count = op->count; op->count = 0; @@ -149,29 +152,27 @@ void cdemu_134b(struct bregs *regs) { // FIXME ElTorito Hardcoded - u16 ebda_seg = get_ebda_seg(); SET_INT13ET(regs, size, 0x13); - SET_INT13ET(regs, media, GET_EBDA2(ebda_seg, cdemu.media)); - SET_INT13ET(regs, emulated_drive - , GET_EBDA2(ebda_seg, cdemu.emulated_extdrive)); - struct drive_s *drive_gf = GET_EBDA2(ebda_seg, cdemu.emulated_drive_gf); + SET_INT13ET(regs, media, GET_LOW(CDEmu.media)); + SET_INT13ET(regs, emulated_drive, GET_LOW(CDEmu.emulated_extdrive)); + struct drive_s *drive_gf = GET_LOW(CDEmu.emulated_drive_gf); u8 cntl_id = 0; if (drive_gf) cntl_id = GET_GLOBALFLAT(drive_gf->cntl_id); SET_INT13ET(regs, controller_index, cntl_id / 2); SET_INT13ET(regs, device_spec, cntl_id % 2); - SET_INT13ET(regs, ilba, GET_EBDA2(ebda_seg, cdemu.ilba)); - SET_INT13ET(regs, buffer_segment, GET_EBDA2(ebda_seg, cdemu.buffer_segment)); - SET_INT13ET(regs, load_segment, GET_EBDA2(ebda_seg, cdemu.load_segment)); - SET_INT13ET(regs, sector_count, GET_EBDA2(ebda_seg, cdemu.sector_count)); - SET_INT13ET(regs, cylinders, GET_EBDA2(ebda_seg, cdemu.lchs.cylinders)); - SET_INT13ET(regs, sectors, GET_EBDA2(ebda_seg, cdemu.lchs.spt)); - SET_INT13ET(regs, heads, GET_EBDA2(ebda_seg, cdemu.lchs.heads)); + SET_INT13ET(regs, ilba, GET_LOW(CDEmu.ilba)); + SET_INT13ET(regs, buffer_segment, GET_LOW(CDEmu.buffer_segment)); + SET_INT13ET(regs, load_segment, GET_LOW(CDEmu.load_segment)); + SET_INT13ET(regs, sector_count, GET_LOW(CDEmu.sector_count)); + SET_INT13ET(regs, cylinders, GET_LOW(CDEmu.lchs.cylinders)); + SET_INT13ET(regs, sectors, GET_LOW(CDEmu.lchs.spt)); + SET_INT13ET(regs, heads, GET_LOW(CDEmu.lchs.heads));
// If we have to terminate emulation if (regs->al == 0x00) { // FIXME ElTorito Various. Should be handled accordingly to spec - SET_EBDA2(ebda_seg, cdemu.active, 0x00); // bye bye + SET_LOW(CDEmu.active, 0x00); // bye bye
// XXX - update floppy/hd count. } @@ -187,6 +188,7 @@ cdemu_134b(struct bregs *regs) int cdrom_boot(struct drive_s *drive_g) { + ASSERT32FLAT(); struct disk_op_s dop; int cdid = getDriveId(EXTTYPE_CD, drive_g); memset(&dop, 0, sizeof(dop)); @@ -202,7 +204,7 @@ cdrom_boot(struct drive_s *drive_g) u8 buffer[2048]; dop.lba = 0x11; dop.count = 1; - dop.buf_fl = MAKE_FLATPTR(GET_SEG(SS), buffer); + dop.buf_fl = buffer; ret = cdb_read(&dop); if (ret) return 3; @@ -237,23 +239,22 @@ cdrom_boot(struct drive_s *drive_g) if (buffer[0x20] != 0x88) return 11; // Bootable
- u16 ebda_seg = get_ebda_seg(); u8 media = buffer[0x21]; - SET_EBDA2(ebda_seg, cdemu.media, media); + CDEmu.media = media;
- SET_EBDA2(ebda_seg, cdemu.emulated_drive_gf, dop.drive_g); + CDEmu.emulated_drive_gf = dop.drive_g;
u16 boot_segment = *(u16*)&buffer[0x22]; if (!boot_segment) boot_segment = 0x07C0; - SET_EBDA2(ebda_seg, cdemu.load_segment, boot_segment); - SET_EBDA2(ebda_seg, cdemu.buffer_segment, 0x0000); + CDEmu.load_segment = boot_segment; + CDEmu.buffer_segment = 0x0000;
u16 nbsectors = *(u16*)&buffer[0x26]; - SET_EBDA2(ebda_seg, cdemu.sector_count, nbsectors); + CDEmu.sector_count = nbsectors;
lba = *(u32*)&buffer[0x28]; - SET_EBDA2(ebda_seg, cdemu.ilba, lba); + CDEmu.ilba = lba;
// And we read the image in memory dop.lba = lba; @@ -265,7 +266,7 @@ cdrom_boot(struct drive_s *drive_g)
if (media == 0) { // No emulation requested - return success. - SET_EBDA2(ebda_seg, cdemu.emulated_extdrive, EXTSTART_CD + cdid); + CDEmu.emulated_extdrive = EXTSTART_CD + cdid; return 0; }
@@ -277,30 +278,30 @@ cdrom_boot(struct drive_s *drive_g) // number of devices if (media < 4) { // Floppy emulation - SET_EBDA2(ebda_seg, cdemu.emulated_extdrive, 0x00); + CDEmu.emulated_extdrive = 0x00; // XXX - get and set actual floppy count. SETBITS_BDA(equipment_list_flags, 0x41);
switch (media) { case 0x01: // 1.2M floppy - SET_EBDA2(ebda_seg, cdemu.lchs.spt, 15); - SET_EBDA2(ebda_seg, cdemu.lchs.cylinders, 80); - SET_EBDA2(ebda_seg, cdemu.lchs.heads, 2); + CDEmu.lchs.spt = 15; + CDEmu.lchs.cylinders = 80; + CDEmu.lchs.heads = 2; break; case 0x02: // 1.44M floppy - SET_EBDA2(ebda_seg, cdemu.lchs.spt, 18); - SET_EBDA2(ebda_seg, cdemu.lchs.cylinders, 80); - SET_EBDA2(ebda_seg, cdemu.lchs.heads, 2); + CDEmu.lchs.spt = 18; + CDEmu.lchs.cylinders = 80; + CDEmu.lchs.heads = 2; break; case 0x03: // 2.88M floppy - SET_EBDA2(ebda_seg, cdemu.lchs.spt, 36); - SET_EBDA2(ebda_seg, cdemu.lchs.cylinders, 80); - SET_EBDA2(ebda_seg, cdemu.lchs.heads, 2); + CDEmu.lchs.spt = 36; + CDEmu.lchs.cylinders = 80; + CDEmu.lchs.heads = 2; break; } } else { // Harddrive emulation - SET_EBDA2(ebda_seg, cdemu.emulated_extdrive, 0x80); + CDEmu.emulated_extdrive = 0x80; SET_BDA(hdcount, GET_BDA(hdcount) + 1);
// Peak at partition table to get chs. @@ -309,14 +310,13 @@ cdrom_boot(struct drive_s *drive_g) u8 cyllow = GET_FARVAR(boot_segment, mbr->partitions[0].last.cyllow); u8 heads = GET_FARVAR(boot_segment, mbr->partitions[0].last.heads);
- SET_EBDA2(ebda_seg, cdemu.lchs.spt, sptcyl & 0x3f); - SET_EBDA2(ebda_seg, cdemu.lchs.cylinders - , ((sptcyl<<2)&0x300) + cyllow + 1); - SET_EBDA2(ebda_seg, cdemu.lchs.heads, heads + 1); + CDEmu.lchs.spt = sptcyl & 0x3f; + CDEmu.lchs.cylinders = ((sptcyl<<2)&0x300) + cyllow + 1; + CDEmu.lchs.heads = heads + 1; }
// everything is ok, so from now on, the emulation is active - SET_EBDA2(ebda_seg, cdemu.active, 0x01); + CDEmu.active = 0x01; dprintf(6, "cdemu media=%d\n", media);
return 0; diff --git a/src/coreboot.c b/src/coreboot.c index 4ae44e5..e116a14 100644 --- a/src/coreboot.c +++ b/src/coreboot.c @@ -6,10 +6,11 @@
#include "memmap.h" // add_e820 #include "util.h" // dprintf -#include "biosvar.h" // GET_EBDA #include "lzmadecode.h" // LzmaDecode #include "smbios.h" // smbios_init #include "boot.h" // boot_add_cbfs +#include "disk.h" // MAXDESCSIZE +#include "config.h" // CONFIG_*
/**************************************************************** diff --git a/src/disk.c b/src/disk.c index 706b9f4..9f02a21 100644 --- a/src/disk.c +++ b/src/disk.c @@ -60,14 +60,13 @@ fillLCHS(struct drive_s *drive_g, u16 *nlc, u16 *nlh, u16 *nlspt) { if (CONFIG_CDROM_EMU && drive_g == GLOBALFLAT2GLOBAL(GET_GLOBAL(cdemu_drive_gf))) { - // Emulated drive - get info from ebda. (It's not possible to + // Emulated drive - get info from CDEmu. (It's not possible to // populate the geometry directly in the driveid because the // geometry is only known after the bios segment is made // read-only). - u16 ebda_seg = get_ebda_seg(); - *nlc = GET_EBDA2(ebda_seg, cdemu.lchs.cylinders); - *nlh = GET_EBDA2(ebda_seg, cdemu.lchs.heads); - *nlspt = GET_EBDA2(ebda_seg, cdemu.lchs.spt); + *nlc = GET_LOW(CDEmu.lchs.cylinders); + *nlh = GET_LOW(CDEmu.lchs.heads); + *nlspt = GET_LOW(CDEmu.lchs.spt); return; } *nlc = GET_GLOBAL(drive_g->lchs.cylinders); @@ -231,7 +230,6 @@ disk_1305(struct bregs *regs, struct drive_s *drive_g) static void noinline disk_1308(struct bregs *regs, struct drive_s *drive_g) { - u16 ebda_seg = get_ebda_seg(); // Get logical geometry from table u16 nlc, nlh, nlspt; fillLCHS(drive_g, &nlc, &nlh, &nlspt); @@ -244,7 +242,7 @@ disk_1308(struct bregs *regs, struct drive_s *drive_g)
if (CONFIG_CDROM_EMU && drive_g == GLOBALFLAT2GLOBAL(GET_GLOBAL(cdemu_drive_gf))) - regs->bx = GET_EBDA2(ebda_seg, cdemu.media) * 2; + regs->bx = GET_LOW(CDEmu.media) * 2; else regs->bx = GET_GLOBAL(drive_g->floppy_type);
@@ -261,8 +259,8 @@ disk_1308(struct bregs *regs, struct drive_s *drive_g) return; }
- if (CONFIG_CDROM_EMU && GET_EBDA2(ebda_seg, cdemu.active)) { - u8 emudrive = GET_EBDA2(ebda_seg, cdemu.emulated_extdrive); + if (CONFIG_CDROM_EMU && GET_LOW(CDEmu.active)) { + u8 emudrive = GET_LOW(CDEmu.emulated_extdrive); if (((emudrive ^ regs->dl) & 0x80) == 0) // Note extra drive due to emulation. count++; @@ -397,15 +395,14 @@ disk_1344(struct bregs *regs, struct drive_s *drive_g) static void disk_134500(struct bregs *regs, struct drive_s *drive_g) { - u16 ebda_seg = get_ebda_seg(); int cdid = regs->dl - EXTSTART_CD; - u8 locks = GET_EBDA2(ebda_seg, cdrom_locks[cdid]); + u8 locks = GET_LOW(CDRom_locks[cdid]); if (locks == 0xff) { regs->al = 1; disk_ret(regs, DISK_RET_ETOOMANYLOCKS); return; } - SET_EBDA2(ebda_seg, cdrom_locks[cdid], locks + 1); + SET_LOW(CDRom_locks[cdid], locks + 1); regs->al = 1; disk_ret(regs, DISK_RET_SUCCESS); } @@ -414,16 +411,15 @@ disk_134500(struct bregs *regs, struct drive_s *drive_g) static void disk_134501(struct bregs *regs, struct drive_s *drive_g) { - u16 ebda_seg = get_ebda_seg(); int cdid = regs->dl - EXTSTART_CD; - u8 locks = GET_EBDA2(ebda_seg, cdrom_locks[cdid]); + u8 locks = GET_LOW(CDRom_locks[cdid]); if (locks == 0x00) { regs->al = 0; disk_ret(regs, DISK_RET_ENOTLOCKED); return; } locks--; - SET_EBDA2(ebda_seg, cdrom_locks[cdid], locks); + SET_LOW(CDRom_locks[cdid], locks); regs->al = (locks ? 1 : 0); disk_ret(regs, DISK_RET_SUCCESS); } @@ -433,7 +429,7 @@ static void disk_134502(struct bregs *regs, struct drive_s *drive_g) { int cdid = regs->dl - EXTSTART_CD; - u8 locks = GET_EBDA(cdrom_locks[cdid]); + u8 locks = GET_LOW(CDRom_locks[cdid]); regs->al = (locks ? 1 : 0); disk_ret(regs, DISK_RET_SUCCESS); } @@ -473,7 +469,7 @@ disk_1346(struct bregs *regs, struct drive_s *drive_g) }
int cdid = regs->dl - EXTSTART_CD; - u8 locks = GET_EBDA(cdrom_locks[cdid]); + u8 locks = GET_LOW(CDRom_locks[cdid]); if (locks != 0) { disk_ret(regs, DISK_RET_ELOCKED); return; @@ -565,11 +561,7 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) u8 channel = 0; SET_INT13DPT(regs, size, 30); if (type == DTYPE_ATA || type == DTYPE_ATAPI) { - u16 ebda_seg = get_ebda_seg(); - - SET_INT13DPT(regs, dpte_segment, ebda_seg); - SET_INT13DPT(regs, dpte_offset - , offsetof(struct extended_bios_data_area_s, dpte)); + SET_INT13DPT(regs, dpte, SEGOFF(SEG_LOW, (u32)&DefaultDPTE));
// Fill in dpte struct atadrive_s *adrive_g = container_of( @@ -602,25 +594,23 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) if (CONFIG_ATA_PIO32) options |= 1<<7;
- SET_EBDA2(ebda_seg, dpte.iobase1, iobase1); - SET_EBDA2(ebda_seg, dpte.iobase2, iobase2 + ATA_CB_DC); - SET_EBDA2(ebda_seg, dpte.prefix, ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) - | ATA_CB_DH_LBA)); - SET_EBDA2(ebda_seg, dpte.unused, 0xcb); - SET_EBDA2(ebda_seg, dpte.irq, irq); - SET_EBDA2(ebda_seg, dpte.blkcount, 1); - SET_EBDA2(ebda_seg, dpte.dma, 0); - SET_EBDA2(ebda_seg, dpte.pio, 0); - SET_EBDA2(ebda_seg, dpte.options, options); - SET_EBDA2(ebda_seg, dpte.reserved, 0); - SET_EBDA2(ebda_seg, dpte.revision, 0x11); - - u8 sum = checksum_far( - ebda_seg, (void*)offsetof(struct extended_bios_data_area_s, dpte), 15); - SET_EBDA2(ebda_seg, dpte.checksum, -sum); + SET_LOW(DefaultDPTE.iobase1, iobase1); + SET_LOW(DefaultDPTE.iobase2, iobase2 + ATA_CB_DC); + SET_LOW(DefaultDPTE.prefix, ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) + | ATA_CB_DH_LBA)); + SET_LOW(DefaultDPTE.unused, 0xcb); + SET_LOW(DefaultDPTE.irq, irq); + SET_LOW(DefaultDPTE.blkcount, 1); + SET_LOW(DefaultDPTE.dma, 0); + SET_LOW(DefaultDPTE.pio, 0); + SET_LOW(DefaultDPTE.options, options); + SET_LOW(DefaultDPTE.reserved, 0); + SET_LOW(DefaultDPTE.revision, 0x11); + + u8 sum = checksum_far(SEG_LOW, &DefaultDPTE, 15); + SET_LOW(DefaultDPTE.checksum, -sum); } else { - SET_INT13DPT(regs, dpte_segment, 0); - SET_INT13DPT(regs, dpte_offset, 0); + SET_INT13DPT(regs, dpte.segoff, 0); bdf = GET_GLOBAL(drive_g->cntl_id); }
@@ -866,9 +856,8 @@ handle_13(struct bregs *regs) cdemu_134b(regs); return; } - u16 ebda_seg = get_ebda_seg(); - if (GET_EBDA2(ebda_seg, cdemu.active)) { - u8 emudrive = GET_EBDA2(ebda_seg, cdemu.emulated_extdrive); + if (GET_LOW(CDEmu.active)) { + u8 emudrive = GET_LOW(CDEmu.emulated_extdrive); if (extdrive == emudrive) { // Access to an emulated drive. struct drive_s *cdemu_g; diff --git a/src/disk.h b/src/disk.h index a675aeb..6c7d8fe 100644 --- a/src/disk.h +++ b/src/disk.h @@ -45,6 +45,24 @@ struct int13ext_s { #define SET_INT13EXT(regs,var,val) \ SET_FARVAR((regs)->ds, ((struct int13ext_s*)((regs)->si+0))->var, (val))
+// 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; +}; + +extern struct dpte_s DefaultDPTE; + // Disk Physical Table definition struct int13dpt_s { u16 size; @@ -54,8 +72,7 @@ struct int13dpt_s { u32 spt; u64 sector_count; u16 blksize; - u16 dpte_offset; - u16 dpte_segment; + struct segoff_s dpte; u16 key; u8 dpi_length; u8 reserved1; @@ -181,6 +198,21 @@ struct chs_s { u16 spt; // # sectors / track };
+// ElTorito Device Emulation data +struct cdemu_s { + struct drive_s *emulated_drive_gf; + u32 ilba; + u16 buffer_segment; + u16 load_segment; + u16 sector_count; + u8 active; + u8 media; + u8 emulated_extdrive; + + // Virtual device + struct chs_s lchs; +}; + struct drive_s { u8 type; // Driver type (DTYPE_*) u8 floppy_type; // Type of floppy (only for floppy drives). @@ -249,6 +281,8 @@ int process_floppy_op(struct disk_op_s *op); void floppy_tick(void);
// cdrom.c +extern u8 CDRom_locks[]; +extern struct cdemu_s CDEmu; extern struct drive_s *cdemu_drive_gf; int process_cdemu_op(struct disk_op_s *op); void cdemu_setup(void);
Clean up includes of biosvar.h.
Rename GET/SET_EBDA2 to GET/SET_EBDA - nearly all users use the extended form now anyway.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/acpi.c | 2 +- src/ahci.c | 2 +- src/biosvar.h | 8 ++------ src/bootsplash.c | 1 - src/memmap.c | 2 +- src/mouse.c | 31 ++++++++++++++++--------------- src/mtrr.c | 2 +- src/pcibios.c | 2 +- src/pciinit.c | 3 ++- src/pirtable.c | 2 +- src/post.c | 2 +- src/smbios.c | 1 - src/xen.h | 3 ++- 13 files changed, 29 insertions(+), 32 deletions(-)
diff --git a/src/acpi.c b/src/acpi.c index 30888b9..5387183 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -8,9 +8,9 @@ #include "acpi.h" // struct rsdp_descriptor #include "util.h" // memcpy #include "pci.h" // pci_find_init_device -#include "biosvar.h" // GET_EBDA #include "pci_ids.h" // PCI_VENDOR_ID_INTEL #include "pci_regs.h" // PCI_INTERRUPT_LINE +#include "ioport.h" // inl #include "paravirt.h"
/****************************************************/ diff --git a/src/ahci.c b/src/ahci.c index 4abfec5..1176dcc 100644 --- a/src/ahci.c +++ b/src/ahci.c @@ -7,7 +7,7 @@ #include "types.h" // u8 #include "ioport.h" // inb #include "util.h" // dprintf -#include "biosvar.h" // GET_EBDA +#include "biosvar.h" // GET_GLOBAL #include "pci.h" // foreachpci #include "pci_ids.h" // PCI_CLASS_STORAGE_OTHER #include "pci_regs.h" // PCI_INTERRUPT_LINE diff --git a/src/biosvar.h b/src/biosvar.h index 4d62df1..b4bd923 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -198,14 +198,10 @@ get_ebda_ptr(void) ASSERT32FLAT(); return MAKE_FLATPTR(get_ebda_seg(), 0); } -#define GET_EBDA2(eseg, var) \ +#define GET_EBDA(eseg, var) \ GET_FARVAR(eseg, ((struct extended_bios_data_area_s *)0)->var) -#define SET_EBDA2(eseg, var, val) \ +#define SET_EBDA(eseg, var, val) \ SET_FARVAR(eseg, ((struct extended_bios_data_area_s *)0)->var, (val)) -#define GET_EBDA(var) \ - GET_EBDA2(get_ebda_seg(), var) -#define SET_EBDA(var, val) \ - SET_EBDA2(get_ebda_seg(), var, (val))
/**************************************************************** diff --git a/src/bootsplash.c b/src/bootsplash.c index 76b72c1..f85f734 100644 --- a/src/bootsplash.c +++ b/src/bootsplash.c @@ -10,7 +10,6 @@ #include "config.h" // CONFIG_* #include "util.h" // dprintf #include "jpeg.h" // splash -#include "biosvar.h" // SET_EBDA #include "paravirt.h" // romfile_find #include "vbe.h" // struct vbe_info #include "bmp.h" diff --git a/src/memmap.c b/src/memmap.c index 56865b4..3783518 100644 --- a/src/memmap.c +++ b/src/memmap.c @@ -5,8 +5,8 @@ // This file may be distributed under the terms of the GNU LGPLv3 license.
#include "memmap.h" // struct e820entry +#include "config.h" // CONFIG_* #include "util.h" // dprintf.h -#include "biosvar.h" // SET_EBDA
/**************************************************************** diff --git a/src/mouse.c b/src/mouse.c index e26cf69..237c8ff 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -52,7 +52,8 @@ mouse_15c20000(struct bregs *regs) static void mouse_15c20001(struct bregs *regs) { - u8 mouse_flags_2 = GET_EBDA(mouse_flag2); + u16 ebda_seg = get_ebda_seg(); + u8 mouse_flags_2 = GET_EBDA(ebda_seg, mouse_flag2); if ((mouse_flags_2 & 0x80) == 0) { set_code_invalid(regs, RET_ENOHANDLER); return; @@ -158,8 +159,8 @@ mouse_15c205(struct bregs *regs) return; } u16 ebda_seg = get_ebda_seg(); - SET_EBDA2(ebda_seg, mouse_flag1, 0x00); - SET_EBDA2(ebda_seg, mouse_flag2, regs->bh); + SET_EBDA(ebda_seg, mouse_flag1, 0x00); + SET_EBDA(ebda_seg, mouse_flag2, regs->bh);
// Reset Mouse mouse_15c201(regs); @@ -227,7 +228,7 @@ mouse_15c207(struct bregs *regs) { struct segoff_s farptr = SEGOFF(regs->es, regs->bx); u16 ebda_seg = get_ebda_seg(); - u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2); + u8 mouse_flags_2 = GET_EBDA(ebda_seg, mouse_flag2); if (! farptr.segoff) { /* remove handler */ if ((mouse_flags_2 & 0x80) != 0) { @@ -238,8 +239,8 @@ mouse_15c207(struct bregs *regs) /* install handler */ mouse_flags_2 |= 0x80; } - SET_EBDA2(ebda_seg, mouse_flag2, mouse_flags_2); - SET_EBDA2(ebda_seg, far_call_pointer, farptr); + SET_EBDA(ebda_seg, mouse_flag2, mouse_flags_2); + SET_EBDA(ebda_seg, far_call_pointer, farptr); set_code_success(regs); }
@@ -279,8 +280,8 @@ process_mouse(u8 data) return;
u16 ebda_seg = get_ebda_seg(); - u8 mouse_flags_1 = GET_EBDA2(ebda_seg, mouse_flag1); - u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2); + u8 mouse_flags_1 = GET_EBDA(ebda_seg, mouse_flag1); + u8 mouse_flags_2 = GET_EBDA(ebda_seg, mouse_flag2);
if (! (mouse_flags_2 & 0x80)) // far call handler not installed @@ -288,20 +289,20 @@ process_mouse(u8 data)
u8 package_count = mouse_flags_2 & 0x07; u8 index = mouse_flags_1 & 0x07; - SET_EBDA2(ebda_seg, mouse_data[index], data); + SET_EBDA(ebda_seg, mouse_data[index], data);
if ((index+1) < package_count) { mouse_flags_1++; - SET_EBDA2(ebda_seg, mouse_flag1, mouse_flags_1); + SET_EBDA(ebda_seg, mouse_flag1, mouse_flags_1); return; }
- u16 status = GET_EBDA2(ebda_seg, mouse_data[0]); - u16 X = GET_EBDA2(ebda_seg, mouse_data[1]); - u16 Y = GET_EBDA2(ebda_seg, mouse_data[2]); - SET_EBDA2(ebda_seg, mouse_flag1, 0); + u16 status = GET_EBDA(ebda_seg, mouse_data[0]); + u16 X = GET_EBDA(ebda_seg, mouse_data[1]); + u16 Y = GET_EBDA(ebda_seg, mouse_data[2]); + SET_EBDA(ebda_seg, mouse_flag1, 0);
- struct segoff_s func = GET_EBDA2(ebda_seg, far_call_pointer); + struct segoff_s func = GET_EBDA(ebda_seg, far_call_pointer); dprintf(16, "mouse farcall s=%04x x=%04x y=%04x func=%04x:%04x\n" , status, X, Y, func.seg, func.offset);
diff --git a/src/mtrr.c b/src/mtrr.c index ec3be4f..0957834 100644 --- a/src/mtrr.c +++ b/src/mtrr.c @@ -5,7 +5,7 @@ // This file may be distributed under the terms of the GNU LGPLv3 license.
#include "util.h" // dprintf -#include "biosvar.h" // GET_EBDA +#include "config.h" // CONFIG_* #include "xen.h" // usingXen
#define MSR_MTRRcap 0x000000fe diff --git a/src/pcibios.c b/src/pcibios.c index 8b792fb..d10cdfd 100644 --- a/src/pcibios.c +++ b/src/pcibios.c @@ -9,7 +9,7 @@ #include "util.h" // handle_1ab1 #include "pci.h" // pci_config_readl #include "bregs.h" // struct bregs -#include "biosvar.h" // GET_EBDA +#include "biosvar.h" // GET_GLOBAL #include "pci_regs.h" // PCI_VENDOR_ID
// romlayout.S diff --git a/src/pciinit.c b/src/pciinit.c index f265662..613a9c0 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -7,9 +7,10 @@
#include "util.h" // dprintf #include "pci.h" // pci_config_readl -#include "biosvar.h" // GET_EBDA #include "pci_ids.h" // PCI_VENDOR_ID_INTEL #include "pci_regs.h" // PCI_COMMAND +#include "ioport.h" // PORT_ATA1_CMD_BASE +#include "config.h" // CONFIG_* #include "xen.h" // usingXen
#define PCI_DEVICE_MEM_MIN 0x1000 diff --git a/src/pirtable.c b/src/pirtable.c index 4c3f1ff..2c328d8 100644 --- a/src/pirtable.c +++ b/src/pirtable.c @@ -6,8 +6,8 @@ // This file may be distributed under the terms of the GNU LGPLv3 license.
#include "pci.h" // struct pir_header +#include "config.h" // CONFIG_* #include "util.h" // checksum -#include "biosvar.h" // SET_EBDA
u16 PirOffset VAR16VISIBLE;
diff --git a/src/post.c b/src/post.c index 3561c0d..695f43f 100644 --- a/src/post.c +++ b/src/post.c @@ -93,7 +93,7 @@ init_bda(void) memset(ebda, 0, sizeof(*ebda)); ebda->size = esize;
- add_e820((u32)MAKE_FLATPTR(ebda_seg, 0), GET_EBDA2(ebda_seg, size) * 1024 + add_e820((u32)MAKE_FLATPTR(ebda_seg, 0), GET_EBDA(ebda_seg, size) * 1024 , E820_RESERVED); }
diff --git a/src/smbios.c b/src/smbios.c index fe1e183..20d2d47 100644 --- a/src/smbios.c +++ b/src/smbios.c @@ -6,7 +6,6 @@ // This file may be distributed under the terms of the GNU LGPLv3 license.
#include "util.h" // dprintf -#include "biosvar.h" // GET_EBDA #include "paravirt.h" // qemu_cfg_smbios_load_field #include "smbios.h" // struct smbios_entry_point
diff --git a/src/xen.h b/src/xen.h index dbd4a37..cc506a6 100644 --- a/src/xen.h +++ b/src/xen.h @@ -1,7 +1,8 @@ #ifndef __XEN_H #define __XEN_H
-#include "util.h" +#include "config.h" // CONFIG_* +#include "types.h" // u32
extern u32 xen_cpuid_base;
Add new GET/SET_LOWFLAT() macros and convert appropriate users to them. The new macros make for slightly better code generation.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/biosvar.h | 6 +++++- src/usb-ehci.c | 40 +++++++++++++++++++--------------------- src/usb-ohci.c | 26 ++++++++++++-------------- src/usb-uhci.c | 43 +++++++++++++++++++++---------------------- 4 files changed, 57 insertions(+), 58 deletions(-)
diff --git a/src/biosvar.h b/src/biosvar.h index b4bd923..294e433 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -250,16 +250,20 @@ static inline u16 get_global_seg(void) { * "Low" memory variables ****************************************************************/
-extern char _datalow_seg; +extern char _datalow_seg, _datalow_base; #define SEG_LOW ((u32)(&_datalow_seg))
#if MODESEGMENT #define GET_LOW(var) GET_FARVAR(SEG_LOW, (var)) #define SET_LOW(var, val) SET_FARVAR(SEG_LOW, (var), (val)) +#define LOWFLAT2LOW(var) ((typeof(var))((void*)(var) - ((u32)(&_datalow_base)))) #else #define GET_LOW(var) (var) #define SET_LOW(var, val) do { (var) = (val); } while (0) +#define LOWFLAT2LOW(var) (var) #endif +#define GET_LOWFLAT(var) GET_LOW(*LOWFLAT2LOW(&(var))) +#define SET_LOWFLAT(var, val) SET_LOW(*LOWFLAT2LOW(&(var)), (val))
/**************************************************************** diff --git a/src/usb-ehci.c b/src/usb-ehci.c index 6494a3d..0c7cec5 100644 --- a/src/usb-ehci.c +++ b/src/usb-ehci.c @@ -520,10 +520,10 @@ ehci_alloc_pipe(struct usbdevice_s *usbdev static void ehci_reset_pipe(struct ehci_pipe *pipe) { - SET_FLATPTR(pipe->qh.qtd_next, EHCI_PTR_TERM); - SET_FLATPTR(pipe->qh.alt_next, EHCI_PTR_TERM); + SET_LOWFLAT(pipe->qh.qtd_next, EHCI_PTR_TERM); + SET_LOWFLAT(pipe->qh.alt_next, EHCI_PTR_TERM); barrier(); - SET_FLATPTR(pipe->qh.token, GET_FLATPTR(pipe->qh.token) & QTD_TOGGLE); + SET_LOWFLAT(pipe->qh.token, GET_LOWFLAT(pipe->qh.token) & QTD_TOGGLE); }
static int @@ -536,15 +536,15 @@ ehci_wait_td(struct ehci_pipe *pipe, struct ehci_qtd *td, int timeout) if (!(status & QTD_STS_ACTIVE)) break; if (check_tsc(end)) { - u32 cur = GET_FLATPTR(pipe->qh.current); - u32 tok = GET_FLATPTR(pipe->qh.token); - u32 next = GET_FLATPTR(pipe->qh.qtd_next); + u32 cur = GET_LOWFLAT(pipe->qh.current); + u32 tok = GET_LOWFLAT(pipe->qh.token); + u32 next = GET_LOWFLAT(pipe->qh.qtd_next); warn_timeout(); dprintf(1, "ehci pipe=%p cur=%08x tok=%08x next=%x td=%p status=%x\n" , pipe, cur, tok, next, td, status); ehci_reset_pipe(pipe); struct usb_ehci_s *cntl = container_of( - GET_FLATPTR(pipe->pipe.cntl), struct usb_ehci_s, usb); + GET_LOWFLAT(pipe->pipe.cntl), struct usb_ehci_s, usb); ehci_waittick(cntl); return -1; } @@ -657,9 +657,9 @@ ehci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize) struct ehci_qtd *tds = (void*)ALIGN((u32)tdsbuf, EHCI_QTD_ALIGN); memset(tds, 0, sizeof(*tds) * STACKQTDS); barrier(); - SET_FLATPTR(pipe->qh.qtd_next, (u32)MAKE_FLATPTR(GET_SEG(SS), tds)); + SET_LOWFLAT(pipe->qh.qtd_next, (u32)MAKE_FLATPTR(GET_SEG(SS), tds));
- u16 maxpacket = GET_FLATPTR(pipe->pipe.maxpacket); + u16 maxpacket = GET_LOWFLAT(pipe->pipe.maxpacket); int tdpos = 0; while (datasize) { struct ehci_qtd *td = &tds[tdpos++ % STACKQTDS]; @@ -698,27 +698,25 @@ ehci_poll_intr(struct usb_pipe *p, void *data) if (! CONFIG_USB_EHCI) return -1; struct ehci_pipe *pipe = container_of(p, struct ehci_pipe, pipe); - struct ehci_qtd *td = GET_FLATPTR(pipe->next_td); - u32 token = GET_FLATPTR(td->token); + struct ehci_qtd *td = GET_LOWFLAT(pipe->next_td); + u32 token = GET_LOWFLAT(td->token); if (token & QTD_STS_ACTIVE) // No intrs found. return -1; // XXX - check for errors.
// Copy data. - int maxpacket = GET_FLATPTR(pipe->pipe.maxpacket); - int pos = td - GET_FLATPTR(pipe->tds); - void *tddata = GET_FLATPTR(pipe->data) + maxpacket * pos; - memcpy_far(GET_SEG(SS), data - , FLATPTR_TO_SEG(tddata), (void*)FLATPTR_TO_OFFSET(tddata) - , maxpacket); + int maxpacket = GET_LOWFLAT(pipe->pipe.maxpacket); + int pos = td - GET_LOWFLAT(pipe->tds); + void *tddata = GET_LOWFLAT(pipe->data) + maxpacket * pos; + memcpy_far(GET_SEG(SS), data, SEG_LOW, LOWFLAT2LOW(tddata), maxpacket);
// Reenable this td. - struct ehci_qtd *next = (void*)(GET_FLATPTR(td->qtd_next) & ~EHCI_PTR_BITS); - SET_FLATPTR(pipe->next_td, next); - SET_FLATPTR(td->buf[0], (u32)tddata); + struct ehci_qtd *next = (void*)(GET_LOWFLAT(td->qtd_next) & ~EHCI_PTR_BITS); + SET_LOWFLAT(pipe->next_td, next); + SET_LOWFLAT(td->buf[0], (u32)tddata); barrier(); - SET_FLATPTR(td->token, (ehci_explen(maxpacket) | QTD_STS_ACTIVE + SET_LOWFLAT(td->token, (ehci_explen(maxpacket) | QTD_STS_ACTIVE | QTD_PID_IN | ehci_maxerr(3)));
return 0; diff --git a/src/usb-ohci.c b/src/usb-ohci.c index b0d0365..7a8b467 100644 --- a/src/usb-ohci.c +++ b/src/usb-ohci.c @@ -504,10 +504,10 @@ ohci_poll_intr(struct usb_pipe *p, void *data) return -1;
struct ohci_pipe *pipe = container_of(p, struct ohci_pipe, pipe); - struct ohci_td *tds = GET_FLATPTR(pipe->tds); - struct ohci_td *head = (void*)(GET_FLATPTR(pipe->ed.hwHeadP) & ~(ED_C|ED_H)); - struct ohci_td *tail = (void*)GET_FLATPTR(pipe->ed.hwTailP); - int count = GET_FLATPTR(pipe->count); + struct ohci_td *tds = GET_LOWFLAT(pipe->tds); + struct ohci_td *head = (void*)(GET_LOWFLAT(pipe->ed.hwHeadP) & ~(ED_C|ED_H)); + struct ohci_td *tail = (void*)GET_LOWFLAT(pipe->ed.hwTailP); + int count = GET_LOWFLAT(pipe->count); int pos = (tail - tds + 1) % count; struct ohci_td *next = &tds[pos]; if (head == next) @@ -516,21 +516,19 @@ ohci_poll_intr(struct usb_pipe *p, void *data) // XXX - check for errors.
// Copy data. - int maxpacket = GET_FLATPTR(pipe->pipe.maxpacket); - void *pipedata = GET_FLATPTR(pipe->data); + int maxpacket = GET_LOWFLAT(pipe->pipe.maxpacket); + void *pipedata = GET_LOWFLAT((pipe->data)); void *intrdata = pipedata + maxpacket * pos; - memcpy_far(GET_SEG(SS), data - , FLATPTR_TO_SEG(intrdata), (void*)FLATPTR_TO_OFFSET(intrdata) - , maxpacket); + memcpy_far(GET_SEG(SS), data, SEG_LOW, LOWFLAT2LOW(intrdata), maxpacket);
// Reenable this td. - SET_FLATPTR(tail->hwINFO, TD_DP_IN | TD_T_TOGGLE | TD_CC); + SET_LOWFLAT(tail->hwINFO, TD_DP_IN | TD_T_TOGGLE | TD_CC); intrdata = pipedata + maxpacket * (tail-tds); - SET_FLATPTR(tail->hwCBP, (u32)intrdata); - SET_FLATPTR(tail->hwNextTD, (u32)next); - SET_FLATPTR(tail->hwBE, (u32)intrdata + maxpacket - 1); + SET_LOWFLAT(tail->hwCBP, (u32)intrdata); + SET_LOWFLAT(tail->hwNextTD, (u32)next); + SET_LOWFLAT(tail->hwBE, (u32)intrdata + maxpacket - 1); barrier(); - SET_FLATPTR(pipe->ed.hwTailP, (u32)next); + SET_LOWFLAT(pipe->ed.hwTailP, (u32)next);
return 0; } diff --git a/src/usb-uhci.c b/src/usb-uhci.c index b2677b8..d43114a 100644 --- a/src/usb-uhci.c +++ b/src/usb-uhci.c @@ -388,18 +388,18 @@ wait_pipe(struct uhci_pipe *pipe, int timeout) { u64 end = calc_future_tsc(timeout); for (;;) { - u32 el_link = GET_FLATPTR(pipe->qh.element); + u32 el_link = GET_LOWFLAT(pipe->qh.element); if (el_link & UHCI_PTR_TERM) return 0; if (check_tsc(end)) { warn_timeout(); - u16 iobase = GET_FLATPTR(pipe->iobase); + u16 iobase = GET_LOWFLAT(pipe->iobase); struct uhci_td *td = (void*)(el_link & ~UHCI_PTR_BITS); dprintf(1, "Timeout on wait_pipe %p (td=%p s=%x c=%x/%x)\n" - , pipe, (void*)el_link, GET_FLATPTR(td->status) + , pipe, (void*)el_link, GET_LOWFLAT(td->status) , inw(iobase + USBCMD) , inw(iobase + USBSTS)); - SET_FLATPTR(pipe->qh.element, UHCI_PTR_TERM); + SET_LOWFLAT(pipe->qh.element, UHCI_PTR_TERM); uhci_waittick(iobase); return -1; } @@ -497,11 +497,11 @@ uhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize) struct uhci_pipe *pipe = container_of(p, struct uhci_pipe, pipe); dprintf(7, "uhci_send_bulk qh=%p dir=%d data=%p size=%d\n" , &pipe->qh, dir, data, datasize); - int maxpacket = GET_FLATPTR(pipe->pipe.maxpacket); - int lowspeed = GET_FLATPTR(pipe->pipe.speed); - int devaddr = (GET_FLATPTR(pipe->pipe.devaddr) - | (GET_FLATPTR(pipe->pipe.ep) << 7)); - int toggle = GET_FLATPTR(pipe->toggle) ? TD_TOKEN_TOGGLE : 0; + int maxpacket = GET_LOWFLAT(pipe->pipe.maxpacket); + int lowspeed = GET_LOWFLAT(pipe->pipe.speed); + int devaddr = (GET_LOWFLAT(pipe->pipe.devaddr) + | (GET_LOWFLAT(pipe->pipe.ep) << 7)); + int toggle = GET_LOWFLAT(pipe->toggle) ? TD_TOKEN_TOGGLE : 0;
// Allocate 4 tds on stack (16byte aligned) u8 tdsbuf[sizeof(struct uhci_td) * STACKTDS + TDALIGN - 1]; @@ -510,7 +510,7 @@ uhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize)
// Enable tds barrier(); - SET_FLATPTR(pipe->qh.element, (u32)MAKE_FLATPTR(GET_SEG(SS), tds)); + SET_LOWFLAT(pipe->qh.element, (u32)MAKE_FLATPTR(GET_SEG(SS), tds));
int tdpos = 0; while (datasize) { @@ -537,12 +537,12 @@ uhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize) data += transfer; datasize -= transfer; } - SET_FLATPTR(pipe->toggle, !!toggle); + SET_LOWFLAT(pipe->toggle, !!toggle); return wait_pipe(pipe, 5000); fail: dprintf(1, "uhci_send_bulk failed\n"); - SET_FLATPTR(pipe->qh.element, UHCI_PTR_TERM); - uhci_waittick(GET_FLATPTR(pipe->iobase)); + SET_LOWFLAT(pipe->qh.element, UHCI_PTR_TERM); + uhci_waittick(GET_LOWFLAT(pipe->iobase)); return -1; }
@@ -554,25 +554,24 @@ uhci_poll_intr(struct usb_pipe *p, void *data) return -1;
struct uhci_pipe *pipe = container_of(p, struct uhci_pipe, pipe); - struct uhci_td *td = GET_FLATPTR(pipe->next_td); - u32 status = GET_FLATPTR(td->status); - u32 token = GET_FLATPTR(td->token); + struct uhci_td *td = GET_LOWFLAT(pipe->next_td); + u32 status = GET_LOWFLAT(td->status); + u32 token = GET_LOWFLAT(td->token); if (status & TD_CTRL_ACTIVE) // No intrs found. return -1; // XXX - check for errors.
// Copy data. - void *tddata = GET_FLATPTR(td->buffer); - memcpy_far(GET_SEG(SS), data - , FLATPTR_TO_SEG(tddata), (void*)FLATPTR_TO_OFFSET(tddata) + void *tddata = GET_LOWFLAT(td->buffer); + memcpy_far(GET_SEG(SS), data, SEG_LOW, LOWFLAT2LOW(tddata) , uhci_expected_length(token));
// Reenable this td. - struct uhci_td *next = (void*)(GET_FLATPTR(td->link) & ~UHCI_PTR_BITS); - SET_FLATPTR(pipe->next_td, next); + struct uhci_td *next = (void*)(GET_LOWFLAT(td->link) & ~UHCI_PTR_BITS); + SET_LOWFLAT(pipe->next_td, next); barrier(); - SET_FLATPTR(td->status, (uhci_maxerr(0) | (status & TD_CTRL_LS) + SET_LOWFLAT(td->status, (uhci_maxerr(0) | (status & TD_CTRL_LS) | TD_CTRL_ACTIVE));
return 0;