]> xenbits.xensource.com Git - seabios.git/commitdiff
Avoid runtime relocation of 16bit "low" mem - calculate at build instead.
authorKevin O'Connor <kevin@koconnor.net>
Sat, 9 Jun 2012 01:14:19 +0000 (21:14 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Sat, 9 Jun 2012 01:26:26 +0000 (21:26 -0400)
Some 16bit accesses to "low" mem variables use 16bit relocations
instead of the normal 32bit relocations.  This causes build problems
if the "low" mem sections move more than 64K during relocation.

The final location of the "low" memory can be determined during the
build, so link the 16bit code with the final post-reloc location of
the "low" mem variables instead.  This eliminates the need to do these
runtime relocations on the 16bit code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
src/biosvar.h
src/pmm.c
src/post.c
tools/layoutrom.py

index fd2f1bf949fa47a6fdb3ddcbcd6ceadb92462c05..eceee54fd5dee57d47211354e5a91dee80e9b15f 100644 (file)
@@ -250,13 +250,13 @@ static inline u16 get_global_seg(void) {
  * "Low" memory variables
  ****************************************************************/
 
-extern u8 _datalow_seg, _datalow_base[];
+extern u8 _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))
+#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)
index 5d43645e50f8c7b90ee5ce309893cf4a36495a28..1addb411574b160b23c31eb7b4cfff7f51cbfa3b 100644 (file)
--- a/src/pmm.c
+++ b/src/pmm.c
@@ -170,13 +170,6 @@ static struct allocinfo_s *RomBase;
 
 #define OPROM_HEADER_RESERVE 16
 
-// Return maximum address of read/writable "low mem" 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;
-}
-
 // Return the memory position up to which roms may be located.
 u32
 rom_get_top(void)
@@ -199,8 +192,8 @@ rom_reserve(u32 size)
     u32 newend = ALIGN(RomEnd + size, OPTION_ROM_ALIGN) + OPROM_HEADER_RESERVE;
     if (newend > (u32)RomBase->allocend)
         return NULL;
-    if (newend < (u32)_datalow_base + OPROM_HEADER_RESERVE)
-        newend = (u32)_datalow_base + OPROM_HEADER_RESERVE;
+    if (newend < (u32)datalow_base + OPROM_HEADER_RESERVE)
+        newend = (u32)datalow_base + OPROM_HEADER_RESERVE;
     RomBase->data = RomBase->dataend = (void*)newend;
     return (void*)RomEnd;
 }
@@ -253,7 +246,8 @@ 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, _datalow_base + OPROM_HEADER_RESERVE, (void*)lowmemend());
+    extern u8 final_datalow_start[];
+    addSpace(&ZoneLow, datalow_base + OPROM_HEADER_RESERVE, final_datalow_start);
     RomBase = findLast(&ZoneLow);
     if (highram) {
         addSpace(&ZoneHigh, (void*)highram
index 1d0d35aa68b268911a446298eae34f47d4043cf8..3101505727380e990916bcba6d9466793ab2675c 100644 (file)
@@ -97,7 +97,7 @@ init_bda(void)
              , E820_RESERVED);
 
     // Init extra stack
-    StackPos = (void*)(&ExtraStack[BUILD_EXTRA_STACK_SIZE] - _datalow_base);
+    StackPos = (void*)(&ExtraStack[BUILD_EXTRA_STACK_SIZE] - datalow_base);
 }
 
 static void
@@ -293,14 +293,14 @@ maininit(void)
 
 // Relocation fixup code that runs at new address after relocation complete.
 static void
-afterReloc(void *datalow)
+afterReloc(void)
 {
     // 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);
+    extern u8 datalow_start[], datalow_end[], final_datalow_start[];
+    memmove(final_datalow_start, datalow_start, datalow_end - datalow_start);
 
     // Run main code
     maininit();
@@ -331,24 +331,20 @@ reloc_init(void)
     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[];
+    extern u8 datalow_start[], datalow_end[], final_datalow_start[];
 
     // Allocate space for init code.
     u32 initsize = code32init_end - code32init_start;
     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)
+    if (!codedest)
         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);
+            , datalow_start, final_datalow_start, datalow_end - datalow_start);
     updateRelocs(code32flat_start, _reloc_datalow_start, _reloc_datalow_end
-                 , datalow - (void*)datalow_start);
+                 , final_datalow_start - datalow_start);
     dprintf(1, "Relocating init from %p to %p (size %d)\n"
             , code32init_start, codedest, initsize);
     s32 delta = codedest - (void*)code32init_start;
@@ -358,9 +354,9 @@ reloc_init(void)
     updateRelocs(code32flat_start, _reloc_init_start, _reloc_init_end, delta);
 
     // Call maininit() in relocated code.
-    void (*func)(void*) = (void*)afterReloc + delta;
+    void (*func)(void) = (void*)afterReloc + delta;
     barrier();
-    func(datalow);
+    func();
 }
 
 // Setup for code relocation and then call reloc_init
index 74b410f4663aec799332f8d7d0d6c6f3432cdd7f..7a7d08c20a2087a47c2b62e61b9f48e9572b9351 100755 (executable)
@@ -48,8 +48,6 @@ def setSectionsStart(sections, endaddr, minalign=1, segoffset=0):
         totspace = alignpos(totspace, section.align) + section.size
     startaddr = (endaddr - totspace) / minalign * minalign
     curaddr = startaddr
-    # out = [(addr, sectioninfo), ...]
-    out = []
     for section in sections:
         curaddr = alignpos(curaddr, section.align)
         section.finalloc = curaddr
@@ -159,7 +157,7 @@ class LayoutInfo:
     sections32flat = sec32flat_start = sec32flat_align = None
     sections32init = sec32init_start = sec32init_align = None
     sections32low = sec32low_start = sec32low_align = None
-    datalow_base = None
+    datalow_base = final_sec32low_start = None
 
 # Determine final memory addresses for sections
 def doLayout(sections, genreloc):
@@ -219,13 +217,17 @@ def doLayout(sections, genreloc):
     li.sections32low = getSectionsCategory(sections, '32low')
     if genreloc:
         sec32low_top = li.sec32init_start
-        datalow_base = min(BUILD_BIOS_ADDR, li.sec32flat_start) - 64*1024
+        final_sec32low_top = min(BUILD_BIOS_ADDR, li.sec32flat_start)
     else:
         sec32low_top = min(BUILD_BIOS_ADDR, li.sec32init_start)
-        datalow_base = sec32low_top - 64*1024
+        final_sec32low_top = sec32low_top
+    relocdelta = final_sec32low_top - sec32low_top
+    datalow_base = final_sec32low_top - 64*1024
     li.datalow_base = max(BUILD_ROM_START, alignpos(datalow_base, 2*1024))
     li.sec32low_start, li.sec32low_align = setSectionsStart(
-        li.sections32low, sec32low_top, 16, segoffset=li.datalow_base)
+        li.sections32low, sec32low_top, 16
+        , segoffset=li.datalow_base - relocdelta)
+    li.final_sec32low_start = li.sec32low_start + relocdelta
 
     # Print statistics
     size16 = BUILD_BIOS_ADDR + BUILD_BIOS_SIZE - li.sec16_start
@@ -311,7 +313,7 @@ def getSectionsStart(sections, defaddr=0):
 def writeLinkerScripts(li, entrysym, genreloc, out16, out32seg, out32flat):
     # Write 16bit linker script
     out = outXRefs(li.sections16, useseg=1) + """
-    _datalow_base = 0x%x ;
+    datalow_base = 0x%x ;
     _datalow_seg = 0x%x ;
 
     code16_start = 0x%x ;
@@ -352,8 +354,7 @@ def writeLinkerScripts(li, entrysym, genreloc, out16, out32seg, out32flat):
         initrelocs = getRelocs(
             li.sections32flat + li.sections32low + li.sections16
             + li.sections32seg, category='32init')
-        lowrelocs = getRelocs(
-            li.sections16 + li.sections32seg + sections32all, category='32low')
+        lowrelocs = getRelocs(sections32all, category='32low')
         relocstr = (strRelocs("_reloc_abs", "code32init_start", absrelocs)
                     + strRelocs("_reloc_rel", "code32init_start", relrelocs)
                     + strRelocs("_reloc_init", "code32flat_start", initrelocs)
@@ -363,8 +364,8 @@ def writeLinkerScripts(li, entrysym, genreloc, out16, out32seg, out32flat):
     out = outXRefs(sections32all) + """
     %s = 0x%x ;
     _reloc_min_align = 0x%x ;
-    _datalow_base = 0x%x ;
-    _datalow_min_align = 0x%x ;
+    datalow_base = 0x%x ;
+    final_datalow_start = 0x%x ;
 
     code32flat_start = 0x%x ;
     .text code32flat_start : {
@@ -385,7 +386,7 @@ def writeLinkerScripts(li, entrysym, genreloc, out16, out32seg, out32flat):
 """ % (entrysym.name, entrysympos,
        li.sec32init_align,
        li.datalow_base,
-       li.sec32low_align,
+       li.final_sec32low_start,
        sec32all_start,
        relocstr,
        outRelSections(li.sections32low, 'code32flat_start'),