[SeaBIOS] [RFC] [PATCH 1/2] Implement support for transitioning from 16 bit to 32 bit

Kevin O'Connor kevin at koconnor.net
Wed Nov 24 04:44:12 CET 2010


On Tue, Nov 23, 2010 at 08:30:24PM -0500, Kevin O'Connor wrote:
> On Tue, Nov 23, 2010 at 02:54:57PM +0100, Gerd Hoffmann wrote:
> > On 11/23/10 14:24, Kevin O'Connor wrote:
> > >On Tue, Nov 23, 2010 at 11:32:13AM +0100, Gerd Hoffmann wrote:
> > >You need to make sure the 32bit function is only available in 32bit
> > >mode.  See below.
> > 
> > Hmm, still not working for me.

Looks like call32 doesn't work when %esp>64K.  I hacked a patch (see
below), but it's quite ugly.

> > 
> > Is there some way to look at the code generated by gcc?
> > Trying 'objdump -d code16.o' looks bogous (16 vs 32bit issue?)
> 
> I use:
> 
> objdump -m i386 -M i8086 -M suffix -ldr out/code16.o

Actually, this is a little more useful:

objdump -m i386 -M i8086 -M suffix -ldr out/rom16.o

-Kevin


diff --git a/src/romlayout.S b/src/romlayout.S
index a469596..bea7509 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -130,7 +130,10 @@ transition16big:
         movw %ax, %ss  // Assume stack is in segment 0
 
         movl %ecx, %eax
-        retl
+        //retl
+        movl (%esp), %ecx
+        addl $4, %esp
+        jmpl *%ecx
 
 // Call a 16bit function from 16bit mode with a specified cpu register state
 // %eax = address of struct bregs
diff --git a/src/stacks.c b/src/stacks.c
index 7db0e3c..620086b 100644
--- a/src/stacks.c
+++ b/src/stacks.c
@@ -56,17 +56,18 @@ call32(void *func, u32 eax, u32 errret)
     struct descloc_s gdt;
     sgdt(&gdt);
 
-    u32 bkup_ss, bkup_esp;
+    u32 bkup_ss, bkup_esp = 0;
     asm volatile(
         // Backup ss/esp / set esp to flat stack location
+        "  pushl $(" __stringify(BUILD_BIOS_ADDR) " + 1f)\n"
         "  movl %%ss, %0\n"
+        "  movl %1, %%ss\n"
         "  movl %%esp, %1\n"
         "  shll $4, %0\n"
         "  addl %0, %%esp\n"
-        "  movl %%ss, %0\n"
+        "  shrl $4, %0\n"
 
         // Transition to 32bit mode, call func, return to 16bit
-        "  pushl $(" __stringify(BUILD_BIOS_ADDR) " + 1f)\n"
         "  jmp transition32\n"
         "  .code32\n"
         "1:calll *%3\n"
@@ -78,7 +79,8 @@ call32(void *func, u32 eax, u32 errret)
         "2:movl %0, %%ds\n"
         "  movl %0, %%ss\n"
         "  movl %1, %%esp\n"
-        : "=&r" (bkup_ss), "=&r" (bkup_esp), "+a" (eax)
+        "  popl %1\n"
+        : "=&r" (bkup_ss), "+r" (bkup_esp), "+a" (eax)
         : "r" (func)
         : "ecx", "edx", "cc", "memory");
 
@@ -395,3 +397,28 @@ check_preempt(void)
 
     call32(yield_preempt, 0, 0);
 }
+
+extern u32 pci_readl_32(u32 addr);
+#if MODESEGMENT == 0
+u32 VISIBLE32FLAT
+pci_readl_32(u32 addr)
+{
+    dprintf(1, "pci rd32: %x\n", addr);
+    return readl((void*)addr);
+}
+#endif
+
+u32 pci_readl(u32 addr)
+{
+    dprintf(1, "pci read: %x\n", addr);
+    if (MODESEGMENT)
+        return call32(pci_readl_32, addr, -1);
+    return pci_readl_32(addr);
+}
+
+void pci_writel(u32 addr, u32 val)
+{
+    dprintf(1, "pci write: %x, %x\n", addr, val);
+    if (!MODESEGMENT)
+        writel((void*)addr, val);
+}



More information about the SeaBIOS mailing list