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); +}