* Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net [071005 18:31]:
Stefan? I think you wanted to Ack this as well. Alex will then commit.
Sorry for the delay... Please go ahead and commit
Acked-by: Stefan Reinauer stepan@coresystems.de
Alex Beregszaszi wrote:
If you say ack, let me commit this, as I missed my last opportunity to commit :)
this patch changes the real_mode_switch_call_vga() function to jump to the addr given as an argument instead the hardcoded 0xc000.
Also it changes the function to inline assembly and passes the arguments through that.
Can you commit the changes above as separate revisions? First the inline assembly change, then the variable addr stuff. This makes the changes easier to follow.
Signed-off-by: Alex Beregszaszi alex@rtfs.hu
Acked-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Carl-Daniel
Index: util/x86emu/vm86.c
--- util/x86emu/vm86.c (revision 494) +++ util/x86emu/vm86.c (working copy) @@ -5,6 +5,7 @@
- Copyright (C) 2001 University of California. LA-CC Number 01-67.
- Copyright (C) 2005 Nick.Barker9@btinternet.com
- Copyright (C) 2007 coresystems GmbH
- Copyright (C) 2007 Siqon Ltd. (written by Alex Beregszaszi)
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
@@ -98,7 +99,7 @@ );
/* The address arguments to this function are PHYSICAL ADDRESSES */ -static void real_mode_switch_call_vga(unsigned long devfn) +static void real_mode_switch_call_vga(unsigned long devfn, unsigned long addr) { __asm__ __volatile__ ( /* paranoia -- does ecx get saved? not sure. @@ -106,16 +107,12 @@ */ " pushal \n" /* save the stack */
" mov %esp, __stack \n"
" jmp 1f \n" "__stack: .long 0 \n" "1:\n"" mov %%esp, __stack \n"
/* get devfn into %ecx */
" movl %esp, %ebp \n"
// FIXME: why is this 8?
/* load 'our' gdt */" movl 8(%ebp), %ecx \n"
" lgdt %cs:__mygdtaddr \n"
" lgdt %%cs:__mygdtaddr \n"
/* This configures CS properly for real mode. */ " ljmp $0x28, $__rms_16bit\n"
@@ -128,17 +125,17 @@ * configurations (limits, writability, etc.) once * protected mode is turned off. */
" mov $0x30, %ax \n"
" mov %ax, %ds \n"
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov %ax, %ss \n"
" mov $0x30, %%ax \n"
" mov %%ax, %%ds \n"
" mov %%ax, %%es \n"
" mov %%ax, %%fs \n"
" mov %%ax, %%gs \n"
" mov %%ax, %%ss \n"
/* Turn off protection (bit 0 in CR0) */
" movl %cr0, %eax \n"
" andl $0xFFFFFFFE, %eax \n"
" movl %eax, %cr0 \n"
" movl %%cr0, %%eax \n"
" andl $0xFFFFFFFE, %%eax \n"
" movl %%eax, %%cr0 \n"
/* Now really going into real mode */ " ljmp $0, $__rms_real\n"
@@ -148,33 +145,49 @@ * That way we can easily share it between real and * protected, since the 16-bit ESP at segment 0 will * work for any case. */
" mov $0x0, %ax \n"
" mov %ax, %ss \n"
" movl $0x1000, %eax \n"
" movl %eax, %esp \n"
" mov $0x0, %%ax \n"
" mov %%ax, %%ss \n"
" movl $0x1000, %%eax \n"
" movl %%eax, %%esp \n"
/* Load our 16 it idt */
" xor %ax, %ax \n"
" mov %ax, %ds \n"
" xor %%ax, %%ax \n"
" mov %%ax, %%ds \n"
" lidt __myidt \n"
/* Dump zeros in the other segment registers */
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov $0x40, %ax \n"
" mov %ax, %ds \n"
" mov %cx, %ax \n"
" mov %%ax, %%es \n"
" mov %%ax, %%fs \n"
" mov %%ax, %%gs \n"
" mov $0x40, %%ax \n"
" mov %%ax, %%ds \n"
" mov %%cx, %%ax \n"
/* run VGA BIOS at 0xc000:0003 */
" lcall $0xc000, $0x0003\n"
+/* " lcall $0xc000, $0x0003 \n"*/
/* calculate addr */
" mov %%edx, %%ebx \n"
" add $3, %%ebx \n"
" and $0xffff, %%ebx \n"
/* calculate segment */
" and $0xf0000, %%edx \n"
" shr $4, %%edx \n"
" pushw %%dx \n"
" pushw %%bx \n"
" mov %%esp, %%ebp \n"
/* idea from bochs bios' rom_scan */
/* call far ss:[bp+0] */
" .byte 0xff, 0x5e, 0x00 \n"
" add $4, %%esp \n"
- /* If we got here, just about done.
*/
- Need to get back to protected mode
" movl %cr0, %eax \n"
" orl $0x0000001, %eax\n" /* PE = 1 */
" movl %eax, %cr0 \n"
" movl %%cr0, %%eax \n"
" orl $0x0000001, %%eax\n" /* PE = 1 */
" movl %%eax, %%cr0 \n"
/* Now that we are in protected mode
- jump to a 32 bit code segment.
@@ -182,21 +195,23 @@ " data32 ljmp $0x10, $vgarestart\n" "vgarestart:\n" " .code32\n"
" movw $0x18, %ax \n"
" mov %ax, %ds \n"
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov %ax, %ss \n"
" movw $0x18, %%ax \n"
" mov %%ax, %%ds \n"
" mov %%ax, %%es \n"
" mov %%ax, %%fs \n"
" mov %%ax, %%gs \n"
" mov %%ax, %%ss \n"
/* restore proper gdt and idt */
" lgdt %cs:gdtarg \n"
" lgdt %%cs:gdtarg \n"
" lidt idtarg \n"
".globl vga_exit \n" "vga_exit: \n"
" mov __stack, %esp \n"
" popal \n"" mov __stack, %%esp \n"
:
);: "c" (devfn), "d" (addr)
}
@@ -315,8 +330,8 @@ for (i = 0x400; i < 0x500; i++) { *(unsigned char *) i = 0; }
- real_mode_switch_call_vga((dev->bus->secondary << 8) | dev->path.u.pci.devfn);
- real_mode_switch_call_vga((dev->bus->secondary << 8) | dev->path.u.pci.devfn, addr);
}