All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Vesa Jääskeläinen" <chaac@nic.fi>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: Re: [PATCH] Move assembly code out of the kernel
Date: Sun, 17 Aug 2008 14:31:05 +0300	[thread overview]
Message-ID: <48A80BF9.3090000@nic.fi> (raw)
In-Reply-To: <23656916.573861217512511895.JavaMail.chaac@nic.fi>

[-- Attachment #1: Type: text/plain, Size: 479 bytes --]

chaac@nic.fi wrote:
> I have made generic function that does basically the same thing for bios
> service 0x10 (video). In that modification you prepare registers
> structure that will be configured during real mode switching. I am yet
> to commit it for review, but I think it would be more generic way to do
> this. When I come back from my holiday I will commit the code for review.
> 
> So please wait a bit before committing this :)

And here it is :)

Comments are welcome.

[-- Attachment #2: move_vbe_calls_from_kernel_to_vbe_mod.diff --]
[-- Type: text/plain, Size: 29912 bytes --]

Index: conf/i386-pc.rmk
===================================================================
--- conf/i386-pc.rmk	(revision 1815)
+++ conf/i386-pc.rmk	(working copy)
@@ -55,7 +55,7 @@
 	partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
 	machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
 	machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
-	machine/kernel.h machine/pxe.h
+	machine/kernel.h machine/pxe.h machine/bioscall.h
 kernel_img_CFLAGS = $(COMMON_CFLAGS)
 kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
 kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,$(GRUB_MEMORY_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
@@ -231,8 +231,9 @@
 multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For vbe.mod.
-vbe_mod_SOURCES = video/i386/pc/vbe.c video/i386/pc/vbeblit.c \
-		  video/i386/pc/vbefill.c video/i386/pc/vbeutil.c
+vbe_mod_SOURCES = video/i386/pc/vbe.c video/i386/pc/vbebios.c \
+		  video/i386/pc/vbeblit.c video/i386/pc/vbefill.c \
+		  video/i386/pc/vbeutil.c
 vbe_mod_CFLAGS = $(COMMON_CFLAGS)
 vbe_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
Index: kern/i386/pc/startup.S
===================================================================
--- kern/i386/pc/startup.S	(revision 1815)
+++ kern/i386/pc/startup.S	(working copy)
@@ -1625,437 +1625,6 @@
 	popl	%ebp
 	ret
 
-/*
- * grub_vbe_bios_status_t grub_vbe_get_controller_info (struct grub_vbe_info_block *controller_info)
- *
- * Register allocations for parameters:
- * %eax		*controller_info
- */
-FUNCTION(grub_vbe_bios_get_controller_info)
-	pushl	%ebp
-	pushl	%edi
-	pushl	%edx
-
-	movw	%ax, %di	/* Store *controller_info to %edx:%di.  */
-	xorw	%ax, %ax
-	shrl	$4, %eax
-	mov	%eax, %edx	/* prot_to_real destroys %eax.  */
-	
-	call	prot_to_real
-	.code16
-
-	pushw	%es
-
-	movw	%dx, %es	/* *controller_info is now on %es:%di.  */
-	movw	$0x4f00, %ax
-	int	$0x10
-
-	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
-
-	popw	%es
-
-	DATA32 call	real_to_prot
-	.code32
-
-	movl	%edx, %eax
-	andl	$0x0FFFF, %eax	/* Return value in %eax.  */
-	
-	pop	%edx
-	popl	%edi
-	popl	%ebp
-	ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_get_mode_info (grub_uint32_t mode,
- *						  struct grub_vbe_mode_info_block *mode_info)
- *
- * Register allocations for parameters:
- * %eax		mode
- * %edx		*mode_info
- */
-FUNCTION(grub_vbe_bios_get_mode_info)
-	pushl   %ebp
-	pushl   %edi
-
-	movl	%eax, %ecx	/* Store mode number to %ecx.  */
-
-	movw    %dx, %di	/* Store *mode_info to %edx:%di.  */
-	xorw    %dx, %dx
-	shrl    $4, %edx
-
-	call    prot_to_real
-	.code16
-
-	pushw   %es
-
-	movw    %dx, %es	/* *mode_info is now on %es:%di.  */
-	movw    $0x4f01, %ax
-	int     $0x10
-
-	movw    %ax, %dx        /* real_to_prot destroys %eax.  */
-
-	popw    %es
-
-	DATA32 call     real_to_prot
-	.code32
-
-	movl    %edx, %eax
-	andl    $0x0FFFF, %eax  /* Return value in %eax.  */
-
-	popl    %edi
-	popl    %ebp
-	ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_set_mode (grub_uint32_t mode,
- *					     struct grub_vbe_crtc_info_block *crtc_info)
- *
- * Register allocations for parameters:
- * %eax		mode
- * %edx		*crtc_info
- */
-FUNCTION(grub_vbe_bios_set_mode)
-	pushl	%ebp
-	pushl	%ebx
-	pushl	%edi
-
-	movl	%eax, %ebx	/* Store mode in %ebx.  */
-
-	movw    %dx, %di	/* Store *crtc_info to %edx:%di.  */
-	xorw    %dx, %dx
-	shrl    $4, %edx
-
-	call    prot_to_real
-	.code16
-
-	pushw   %es
-
-	movw    %dx, %es	/* *crtc_info is now on %es:%di.  */
-
-	movw	$0x4f02, %ax
-	int	$0x10
-
-	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
-
-	popw	%es
-
-	DATA32 call	real_to_prot
-	.code32
-	
-	movw	%dx, %ax
-	andl	$0xFFFF, %eax	/* Return value in %eax.  */
-
-	popl	%edi
-	popl	%ebx
-	popl	%ebp
-	ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_get_mode (grub_uint32_t *mode)
- *
- * Register allocations for parameters:
- * %eax		*mode
- */
-FUNCTION(grub_vbe_bios_get_mode)
-	pushl   %ebp
-	pushl   %ebx
-	pushl	%edi
-	pushl	%edx
-	pushl	%eax		/* Push *mode to stack.  */
-
-	call    prot_to_real
-	.code16
-
-	movw    $0x4f03, %ax
-	int     $0x10
-
-	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
-
-	DATA32 call     real_to_prot
-	.code32
-
-	popl	%edi		/* Pops *mode from stack to %edi.  */
-	andl	$0xFFFF, %ebx
-	movl	%ebx, (%edi)
-
-	movw	%dx, %ax
-	andl	$0xFFFF, %eax	/* Return value in %eax.  */
-
-	popl	%edx
-	popl	%edi
-	popl    %ebx
-	popl    %ebp
-	ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_set_memory_window (grub_uint32_t window,
- *						      grub_uint32_t position);
- *
- * Register allocations for parameters:
- * %eax		window
- * %edx		position
- */
-FUNCTION(grub_vbe_bios_set_memory_window)
-	pushl	%ebp
-	pushl	%ebx
-
-	movl	%eax, %ebx
-
-	call	prot_to_real
-	.code16
-
-	movw	$0x4f05, %ax
-	andw	$0x00ff, %bx	/* BL = window, BH = 0, Set memory window.  */
-	int	$0x10
-
-	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
-
-	DATA32 call	real_to_prot
-	.code32
-	
-	movw	%dx, %ax
-	andl	$0xFFFF, %eax	/* Return value in %eax.  */
-
-	popl	%ebx
-	popl	%ebp
-	ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_get_memory_window (grub_uint32_t window,
- * 						      grub_uint32_t *position);
- *
- * Register allocations for parameters:
- * %eax		window
- * %edx		*position
- */
-FUNCTION(grub_vbe_bios_get_memory_window)
-	pushl   %ebp
-	pushl   %ebx
-	pushl	%edi
-	pushl	%edx		/* Push *position to stack.  */
-
-	movl	%eax, %ebx	/* Store window in %ebx.  */
-
-	call    prot_to_real
-	.code16
-
-	movw    $0x4f05, %ax
-	andw	$0x00ff, %bx	/* BL = window.  */
-	orw	$0x0100, %bx	/* BH = 1, Get memory window.  */
-	int     $0x10
-
-	movw	%ax, %bx	/* real_to_prot destroys %eax.  */
-
-	DATA32 call     real_to_prot
-	.code32
-
-	popl	%edi		/* pops *position from stack to %edi.  */
-	andl	$0xFFFF, %edx
-	movl	%edx, (%edi)	/* Return position to caller.  */
-
-	movw	%bx, %ax
-	andl	$0xFFFF, %eax	/* Return value in %eax.  */
-
-	popl	%edi
-	popl    %ebx
-	popl    %ebp
-	ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_set_scanline_length (grub_uint32_t length)
- *
- * Register allocations for parameters:
- * %eax		length
- */
-FUNCTION(grub_vbe_bios_set_scanline_length)
-	pushl	%ebp
-	pushl	%ebx
-	pushl	%edx
-
-	movl	%eax, %ecx	/* Store length in %ecx.  */
-
-	call	prot_to_real
-	.code16
-
-	movw	$0x4f06, %ax
-	movw	$0x0002, %bx	/* BL = 2, Set Scan Line in Bytes.  */
-	int	$0x10
-
-	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
-
-	DATA32 call	real_to_prot
-	.code32
-	
-	movw	%dx, %ax
-	andl	$0xFFFF, %eax	/* Return value in %eax.  */
-
-	popl	%edx
-	popl	%ebx
-	popl	%ebp
-	ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_get_scanline_length (grub_uint32_t *length)
- *
- * Register allocations for parameters:
- * %eax		*length
- */
-FUNCTION(grub_vbe_bios_get_scanline_length)
-	pushl   %ebp
-	pushl   %ebx
-	pushl	%edi
-	pushl	%edx		/* Push *length to stack.  */
-
-	call    prot_to_real
-	.code16
-
-	movw    $0x4f06, %ax
-	movw	$0x0001, %bx	/* BL = 1, Get Scan Line Length (in bytes).  */
-	int     $0x10
-
-	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
-
-	DATA32 call     real_to_prot
-	.code32
-
-	popl	%edi		/* Pops *length from stack to %edi.  */
-	andl	$0xFFFF, %ebx
-	movl	%ebx, (%edi)	/* Return length to caller.  */
-
-	movw	%dx, %ax
-	andl	$0xFFFF, %eax	/* Return value in %eax.  */
-
-	popl	%edi
-	popl    %ebx
-	popl    %ebp
-	ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_set_display_start (grub_uint32_t x,
- *						      grub_uint32_t y)
- *
- * Register allocations for parameters:
- * %eax		x
- * %edx		y
- */
-FUNCTION(grub_vbe_bios_set_display_start)
-	pushl	%ebp
-	pushl	%ebx
-
-	movl	%eax, %ecx	/* Store x in %ecx.  */
-
-	call	prot_to_real
-	.code16
-
-	movw	$0x4f07, %ax
-	movw	$0x0080, %bx	/* BL = 80h, Set Display Start 
-				   during Vertical Retrace.  */
-	int	$0x10
-
-	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
-
-	DATA32 call	real_to_prot
-	.code32
-	
-	movw	%dx, %ax
-	andl	$0xFFFF, %eax	/* Return value in %eax.  */
-
-	popl	%ebx
-	popl	%ebp
-	ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_get_display_start (grub_uint32_t *x,
- *						      grub_uint32_t *y)
- *
- * Register allocations for parameters:
- * %eax		*x
- * %edx		*y
- */
-FUNCTION(grub_vbe_bios_get_display_start)
-	pushl   %ebp
-	pushl   %ebx
-	pushl	%edi
-	pushl	%eax		/* Push *x to stack.  */
-	pushl	%edx		/* Push *y to stack.  */
-
-	call    prot_to_real
-	.code16
-
-	movw    $0x4f07, %ax
-	movw	$0x0001, %bx	/* BL = 1, Get Display Start.  */
-	int     $0x10
-
-	movw	%ax, %bx	/* real_to_prot destroys %eax.  */
-
-	DATA32 call     real_to_prot
-	.code32
-
-	popl	%edi		/* Pops *y from stack to %edi.  */
-	andl	$0xFFFF, %edx
-	movl	%edx, (%edi)	/* Return y-position to caller.  */
-
-	popl	%edi		/* Pops *x from stack to %edi.  */
-	andl	$0xFFFF, %ecx
-	movl	%ecx, (%edi)	/* Return x-position to caller.  */
-
-	movw	%bx, %ax
-	andl	$0xFFFF, %eax	/* Return value in %eax.  */
-
-	popl	%edi
-	popl    %ebx
-	popl    %ebp
-	ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_set_palette_data (grub_uint32_t color_count,
- *						     grub_uint32_t start_index,
- *						     struct grub_vbe_palette_data *palette_data)
- *
- * Register allocations for parameters:
- * %eax		color_count
- * %edx		start_index
- * %ecx		*palette_data
- */
-FUNCTION(grub_vbe_bios_set_palette_data)
-	pushl	%ebp
-	pushl	%ebx
-	pushl	%edi
-
-	movl	%eax, %ebx	/* Store color_count in %ebx.  */
-
-	movw    %cx, %di	/* Store *palette_data to %ecx:%di.  */
-	xorw    %cx, %cx
-	shrl    $4, %ecx
-
-	call    prot_to_real
-	.code16
-
-	pushw   %es
-
-	movw    %cx, %es	/* *palette_data is now on %es:%di.  */
-	movw	%bx, %cx	/* color_count is now on %cx.  */
-
-	movw	$0x4f09, %ax
-	xorw	%bx, %bx	/* BL = 0, Set Palette Data.  */
-	int	$0x10
-
-	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
-
-	popw	%es
-
-	DATA32 call	real_to_prot
-	.code32
-	
-	movw	%dx, %ax
-	andl	$0xFFFF, %eax	/* Return value in %eax.  */
-
-	popl	%edi
-	popl	%ebx
-	popl	%ebp
-	ret
-
-
 pxe_rm_entry:
 	.long	0
 
@@ -2153,3 +1722,170 @@
 	popl	%esi
 	popl	%ebp
 	ret
+
+/*
+ * grub_uint32_t grub_bioscall_int10h (struct grub_bioscall_regs *regs,
+ *									   struct grub_bioscall_regs *result_regs)
+ *
+ * Register allocations for parameters:
+ * %eax		*regs
+ * %edx		*result_regs
+ */
+FUNCTION(grub_bioscall_int10h)
+	pushl	%ebp
+	pushl	%ecx
+	pushl	%ebx
+	pushl	%edi
+	pushl	%esi
+
+	/* save address to result register structure */
+	pushl	%edx
+
+	/* just in case, set GDT */
+	lgdt	gdtdesc
+
+	/* setup %esi for bioscall registers copy operation */
+	movl	%eax, %esi
+
+	/* save the protected mode stack */
+	movl	%esp, %eax
+	movl	%eax, protstack
+
+	/* copy bios call registers to realmode stack */
+	xorl	%eax,%eax
+	movw	%ax,%ds
+	movw	%ax,%es
+	movl	$(GRUB_MEMORY_MACHINE_REAL_STACK-16), %eax
+
+	/* register order: ax, cx, dx, bx, si, di, es, ds */
+	/* note: %esi is loaded above.  */
+	movl	$16, %ecx
+ 	movl	%eax, %edi
+	cld
+	rep
+	movsb
+
+	/* set up new stack */
+	movl	$GRUB_MEMORY_MACHINE_REAL_STACK, %eax
+	movl	%eax, %ebp
+
+	/* adjust stack for copied registers */
+	subl	$16, %eax
+	movl	%eax, %esp
+
+	/* set up segment limits */
+	movw	$GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG, %ax
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
+
+	/* this might be an extra step */
+	/* jump to a 16 bit segment */
+	ljmp	$GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $grub_bioscall_int10h_tmpcseg
+
+grub_bioscall_int10h_tmpcseg:
+	.code16
+
+	/* clear the PE bit of CR0 */
+	movl	%cr0, %eax
+	andl 	$(~GRUB_MEMORY_MACHINE_CR0_PE_ON), %eax
+	movl	%eax, %cr0
+
+	/* flush prefetch queue, reload %cs */
+	DATA32	ljmp	$0, $grub_bioscall_int10h_realcseg
+
+grub_bioscall_int10h_realcseg:
+	/* we are in real mode now
+	 * set up the real mode segment registers : DS, SS, ES
+	 */
+	/* zero %eax */
+	xorl	%eax, %eax
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
+	xorl	%edx, %edx
+
+	/* setup registers from stack */
+	popw	%ax
+	popw	%cx
+	popw	%dx
+	popw	%bx
+	popw	%si
+	popw	%di
+	popw	%es
+	popw	%ds
+
+	/* note: bp should equal to sp */
+
+	/* restore interrupts */
+	sti
+
+	/* call BIOS interrupt service function */
+	int		$0x10
+
+	/* disable interrupts */
+	cli
+
+	/* save registers to stack */
+	pushw	%ds
+	pushw	%es
+	pushw	%di
+	pushw	%si
+	pushw	%bx
+	pushw	%dx
+	pushw	%cx
+	pushw	%ax
+
+	/* just in case... load the GDT register */
+	DATA32	ADDR32	lgdt	%cs:gdtdesc
+
+	/* turn on protected mode */
+	movl	%cr0, %eax
+	orl	$GRUB_MEMORY_MACHINE_CR0_PE_ON, %eax
+	movl	%eax, %cr0
+
+	/* jump to relocation, flush prefetch queue, and reload %cs */
+	DATA32	ljmp	$GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $grub_bioscall_int10h_protcseg
+
+	.code32
+grub_bioscall_int10h_protcseg:
+	/* reload other segment registers */
+	movw	$GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %ax
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
+
+	/* get protected mode stack */
+	movl	protstack, %eax
+	movl	%eax, %esp
+	movl	%eax, %ebp
+
+	/* get result register structure address from stack */
+	popl	%edi
+
+	/* register order: ax, cx, dx, bx, si, di, es, ds */
+	/* note: %edi is setup above */
+	movl	$16, %ecx
+ 	movl	$(GRUB_MEMORY_MACHINE_REAL_STACK-16), %esi
+	cld
+	rep
+	movsb
+
+	/* zero %eax */
+	xorl	%eax, %eax
+
+	/* copy %ax from result registers */
+	movw	GRUB_MEMORY_MACHINE_REAL_STACK-16, %ax
+
+	/* Restore modified registers */
+	popl	%esi
+	popl	%edi
+	popl	%ebx
+	popl	%ecx
+	popl	%ebp
+
+	ret
Index: video/i386/pc/vbebios.c
===================================================================
--- video/i386/pc/vbebios.c	(revision 0)
+++ video/i386/pc/vbebios.c	(revision 0)
@@ -0,0 +1,251 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/bioscall.h>
+#include <grub/machine/vbe.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+
+/* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status.  */
+grub_vbe_status_t
+grub_vbe_bios_get_controller_info (struct grub_vbe_info_block *ci)
+{
+  struct grub_bioscall_regs regs;
+  struct grub_bioscall_regs result_regs;
+  grub_uint32_t addr = (grub_uint32_t)ci;
+
+  /* Zero registers.  */
+  grub_memset(&regs, 0, sizeof(regs));
+
+  /* Fill registers.  */
+  regs.es = addr >> 4;
+  regs.di = addr & 0x0F;
+  regs.ax = 0x4F00;
+
+  return grub_bioscall_int10h(&regs, &result_regs);
+}
+
+/* Call VESA BIOS 0x4f01 to get VBE Mode Information, return status.  */
+grub_vbe_status_t
+grub_vbe_bios_get_mode_info (grub_uint32_t mode,
+                             struct grub_vbe_mode_info_block *mode_info)
+{
+  struct grub_bioscall_regs regs;
+  struct grub_bioscall_regs result_regs;
+  grub_uint32_t addr = (grub_uint32_t)mode_info;
+
+  /* Zero registers.  */
+  grub_memset(&regs, 0, sizeof(regs));
+
+  /* Fill registers.  */
+  regs.cx = mode & 0xFFFF;
+  regs.es = addr >> 4;
+  regs.di = addr & 0x0F;
+  regs.ax = 0x4F01;
+
+  return grub_bioscall_int10h(&regs, &result_regs);
+}
+
+/* Call VESA BIOS 0x4f02 to set video mode, return status.  */
+grub_vbe_status_t
+grub_vbe_bios_set_mode (grub_uint32_t mode,
+                        struct grub_vbe_crtc_info_block *crtc_info)
+{
+  struct grub_bioscall_regs regs;
+  struct grub_bioscall_regs result_regs;
+  grub_uint32_t addr = (grub_uint32_t)crtc_info;
+
+  /* Zero registers.  */
+  grub_memset(&regs, 0, sizeof(regs));
+
+  /* Fill registers.  */
+  regs.bx = mode & 0xFFFF;
+  regs.es = addr >> 4;
+  regs.di = addr & 0x0F;
+  regs.ax = 0x4F02;
+
+  return grub_bioscall_int10h(&regs, &result_regs);
+}
+
+/* Call VESA BIOS 0x4f03 to return current VBE Mode, return status.  */
+grub_vbe_status_t grub_vbe_bios_get_mode (grub_uint32_t *mode)
+{
+  struct grub_bioscall_regs regs;
+  struct grub_bioscall_regs result_regs;
+  grub_uint32_t rc;
+
+  /* Zero registers.  */
+  grub_memset(&regs, 0, sizeof(regs));
+
+  /* Fill registers.  */
+  regs.ax = 0x4F03;
+
+  rc = grub_bioscall_int10h(&regs, &result_regs);
+
+  /* Save results.  */
+  *mode = result_regs.bx;
+
+  return rc;
+}
+
+/* Call VESA BIOS 0x4f05 to set memory window, return status.  */
+grub_vbe_status_t grub_vbe_bios_set_memory_window (grub_uint32_t window,
+                                                   grub_uint32_t position)
+{
+  struct grub_bioscall_regs regs;
+  struct grub_bioscall_regs result_regs;
+
+  /* Zero registers.  */
+  grub_memset(&regs, 0, sizeof(regs));
+
+  /* Fill registers.  */
+  regs.bx = window & 0x00FF;
+  regs.dx = position & 0xFFFF;
+  regs.ax = 0x4F05;
+
+  return grub_bioscall_int10h(&regs, &result_regs);
+}
+
+/* Call VESA BIOS 0x4f05 to return memory window, return status.  */
+grub_vbe_status_t grub_vbe_bios_get_memory_window (grub_uint32_t window,
+                                                   grub_uint32_t *position)
+{
+  struct grub_bioscall_regs regs;
+  struct grub_bioscall_regs result_regs;
+  grub_uint32_t rc;
+
+  /* Zero registers.  */
+  grub_memset(&regs, 0, sizeof(regs));
+
+  /* Fill registers.  */
+  regs.bx = (window & 0x00FF) | 0x0100;
+  regs.ax = 0x4F05;
+
+  rc = grub_bioscall_int10h(&regs, &result_regs);
+
+  /* Save results.  */
+  *position = result_regs.dx;
+
+  return rc;
+}
+
+/* Call VESA BIOS 0x4f06 to set scanline length (in bytes), return status.  */
+grub_vbe_status_t grub_vbe_bios_set_scanline_length (grub_uint32_t length)
+{
+  struct grub_bioscall_regs regs;
+  struct grub_bioscall_regs result_regs;
+
+  /* Zero registers.  */
+  grub_memset(&regs, 0, sizeof(regs));
+
+  /* Fill registers.  */
+  regs.bx = 0x0002;
+  regs.cx = length & 0xFFFF;
+  regs.ax = 0x4F06;
+
+  return grub_bioscall_int10h(&regs, &result_regs);
+}
+
+/* Call VESA BIOS 0x4f06 to return scanline length (in bytes, return status.  */
+grub_vbe_status_t grub_vbe_bios_get_scanline_length (grub_uint32_t *length)
+{
+  struct grub_bioscall_regs regs;
+  struct grub_bioscall_regs result_regs;
+  grub_uint32_t rc;
+
+  /* Zero registers.  */
+  grub_memset(&regs, 0, sizeof(regs));
+
+  /* Fill registers.  */
+  regs.bx = 0x0001;
+  regs.ax = 0x4F06;
+
+  rc = grub_bioscall_int10h(&regs, &result_regs);
+
+  /* Save results.  */
+  *length = result_regs.bx;
+
+  return rc;
+}
+
+/* Call VESA BIOS 0x4f07 to set display start, return status.  */
+grub_vbe_status_t grub_vbe_bios_set_display_start (grub_uint32_t x,
+                                                   grub_uint32_t y)
+{
+  struct grub_bioscall_regs regs;
+  struct grub_bioscall_regs result_regs;
+
+  /* Zero registers.  */
+  grub_memset(&regs, 0, sizeof(regs));
+
+  /* Fill registers.  */
+
+  /* BL = 80h, Set Display Start during Vertical Retrace.  */
+  regs.bx = 0x0080;
+  regs.cx = x & 0xFFFF;
+  regs.dx = y & 0xFFFF;
+  regs.ax = 0x4F07;
+
+  return grub_bioscall_int10h(&regs, &result_regs);
+}
+
+/* Call VESA BIOS 0x4f07 to get display start, return status.  */
+grub_vbe_status_t grub_vbe_bios_get_display_start (grub_uint32_t *x,
+                                                   grub_uint32_t *y)
+{
+  struct grub_bioscall_regs regs;
+  struct grub_bioscall_regs result_regs;
+  grub_uint32_t rc;
+
+  /* Zero registers.  */
+  grub_memset(&regs, 0, sizeof(regs));
+
+  /* Fill registers.  */
+  regs.bx = 0x0001;
+  regs.ax = 0x4F07;
+
+  rc = grub_bioscall_int10h(&regs, &result_regs);
+
+  /* Save results.  */
+  *x = result_regs.cx;
+  *y = result_regs.dx;
+
+  return rc;
+}
+
+/* Call VESA BIOS 0x4f09 to set palette data, return status.  */
+grub_vbe_status_t grub_vbe_bios_set_palette_data (grub_uint32_t color_count,
+                                                  grub_uint32_t start_index,
+                                                  struct grub_vbe_palette_data *palette_data)
+{
+  struct grub_bioscall_regs regs;
+  struct grub_bioscall_regs result_regs;
+  grub_uint32_t addr = (grub_uint32_t)palette_data;
+
+  /* Zero registers.  */
+  grub_memset(&regs, 0, sizeof(regs));
+
+  /* Fill registers.  */
+  regs.dx = start_index & 0xFFFF;
+  regs.cx = color_count & 0xFFFF;
+  regs.es = addr >> 4;
+  regs.di = addr & 0x0F;
+  regs.ax = 0x4F09;
+
+  return grub_bioscall_int10h(&regs, &result_regs);
+}

Property changes on: video/i386/pc/vbebios.c
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Index: include/grub/i386/pc/vbe.h
===================================================================
--- include/grub/i386/pc/vbe.h	(revision 1815)
+++ include/grub/i386/pc/vbe.h	(working copy)
@@ -151,48 +151,46 @@
   grub_uint8_t alignment;
 } __attribute__ ((packed));
 
-/* Prototypes for kernel real mode thunks.  */
-
 /* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_controller_info) (struct grub_vbe_info_block *controller_info);
+grub_vbe_status_t grub_vbe_bios_get_controller_info (struct grub_vbe_info_block *controller_info);
 
 /* Call VESA BIOS 0x4f01 to get VBE Mode Information, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_mode_info) (grub_uint32_t mode,
-                                                            struct grub_vbe_mode_info_block *mode_info);
+grub_vbe_status_t grub_vbe_bios_get_mode_info (grub_uint32_t mode,
+                                               struct grub_vbe_mode_info_block *mode_info);
 
 /* Call VESA BIOS 0x4f02 to set video mode, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_mode) (grub_uint32_t mode,
-                                                       struct grub_vbe_crtc_info_block *crtc_info);
+grub_vbe_status_t grub_vbe_bios_set_mode (grub_uint32_t mode,
+                                          struct grub_vbe_crtc_info_block *crtc_info);
 
 /* Call VESA BIOS 0x4f03 to return current VBE Mode, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_mode) (grub_uint32_t *mode);
+grub_vbe_status_t grub_vbe_bios_get_mode (grub_uint32_t *mode);
 
 /* Call VESA BIOS 0x4f05 to set memory window, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_memory_window) (grub_uint32_t window,
-                                                                grub_uint32_t position);
+grub_vbe_status_t grub_vbe_bios_set_memory_window (grub_uint32_t window,
+                                                   grub_uint32_t position);
 
 /* Call VESA BIOS 0x4f05 to return memory window, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_memory_window) (grub_uint32_t window,
-                                                                grub_uint32_t *position);
+grub_vbe_status_t grub_vbe_bios_get_memory_window (grub_uint32_t window,
+                                                   grub_uint32_t *position);
 
 /* Call VESA BIOS 0x4f06 to set scanline length (in bytes), return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_scanline_length) (grub_uint32_t length);
+grub_vbe_status_t grub_vbe_bios_set_scanline_length (grub_uint32_t length);
 
-/* Call VESA BIOS 0x4f06 to return scanline length (in bytes), return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_scanline_length) (grub_uint32_t *length);
+/* Call VESA BIOS 0x4f06 to return scanline length (in bytes, return status.  */
+grub_vbe_status_t grub_vbe_bios_get_scanline_length (grub_uint32_t *length);
 
 /* Call VESA BIOS 0x4f07 to set display start, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_display_start) (grub_uint32_t x,
-                                                                grub_uint32_t y);
+grub_vbe_status_t grub_vbe_bios_set_display_start (grub_uint32_t x,
+                                                   grub_uint32_t y);
 
 /* Call VESA BIOS 0x4f07 to get display start, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_display_start) (grub_uint32_t *x,
-                                                                grub_uint32_t *y);
+grub_vbe_status_t grub_vbe_bios_get_display_start (grub_uint32_t *x,
+                                                   grub_uint32_t *y);
 
 /* Call VESA BIOS 0x4f09 to set palette data, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_palette_data) (grub_uint32_t color_count,
-                                                               grub_uint32_t start_index,
-                                                               struct grub_vbe_palette_data *palette_data);
+grub_vbe_status_t grub_vbe_bios_set_palette_data (grub_uint32_t color_count,
+                                                  grub_uint32_t start_index,
+                                                  struct grub_vbe_palette_data *palette_data);
 
 /* Prototypes for helper functions.  */
 
Index: include/grub/i386/pc/bioscall.h
===================================================================
--- include/grub/i386/pc/bioscall.h	(revision 0)
+++ include/grub/i386/pc/bioscall.h	(revision 0)
@@ -0,0 +1,44 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BIOSCALL_MACHINE_HEADER
+#define GRUB_BIOSCALL_MACHINE_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+/* Registers for real mode BIOS call.  */
+struct grub_bioscall_regs
+{
+  grub_uint16_t ax;
+  grub_uint16_t cx;
+  grub_uint16_t dx;
+  grub_uint16_t bx;
+
+  grub_uint16_t si;
+  grub_uint16_t di;
+
+  grub_uint16_t es;
+  grub_uint16_t ds;
+} __attribute__ ((packed));
+
+/* Prototypes for kernel real mode helpers.  */
+grub_uint32_t EXPORT_FUNC(grub_bioscall_int10h) (struct grub_bioscall_regs *regs,
+                                                 struct grub_bioscall_regs *result_regs);
+
+#endif /* ! GRUB_BIOSCALL_MACHINE_HEADER */

Property changes on: include/grub/i386/pc/bioscall.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 1815)
+++ ChangeLog	(working copy)
@@ -1,3 +1,40 @@
+2008-08-17  Vesa Jääskeläinen  <chaac@nic.fi>
+
+	* conf/i386-pc.rmk (kernel_img_HEADERS): Add machine/bioscall.h.
+	(vbe_mod_SOURCES): Add video/i386/pc/vbebios.c.
+
+	* include/grub/i386/pc/bioscall.h: New file.
+
+	* include/grub/i386/pc/vbe.h (grub_vbe_bios_get_controller_info):
+	Moved from kernel to vbe.mod.
+	(grub_vbe_bios_get_mode_info): Likewise.
+	(grub_vbe_bios_set_mode): Likewise.
+	(grub_vbe_bios_get_mode): Likewise.
+	(grub_vbe_bios_set_memory_window): Likewise.
+	(grub_vbe_bios_get_memory_window): Likewise.
+	(grub_vbe_bios_set_scanline_length): Likewise.
+	(grub_vbe_bios_get_scanline_length): Likewise.
+	(grub_vbe_bios_set_display_start): Likewise.
+	(grub_vbe_bios_get_display_start): Likewise.
+	(grub_vbe_bios_set_palette_data): Likewise.
+
+	* kern/i386/pc/startup.s (grub_vbe_bios_get_controller_info):
+	Removed.
+	(grub_vbe_bios_get_controller_info): Likewise.
+	(grub_vbe_bios_get_mode_info): Likewise.
+	(grub_vbe_bios_set_mode): Likewise.
+	(grub_vbe_bios_get_mode): Likewise.
+	(grub_vbe_bios_set_memory_window): Likewise.
+	(grub_vbe_bios_get_memory_window): Likewise.
+	(grub_vbe_bios_set_scanline_length): Likewise.
+	(grub_vbe_bios_get_scanline_length): Likewise.
+	(grub_vbe_bios_set_display_start): Likewise.
+	(grub_vbe_bios_get_display_start): Likewise.
+	(grub_vbe_bios_set_palette_data): Likewise.
+	(grub_bioscall_int10h): New function.
+
+	* video/i386/pc/vbebios.c: New file.
+
 2008-08-17  Carles Pina i Estany  <carles@pina.cat>
 
         * menu/normal.c (run_menu): Add Home and End keys in grub-menu.

  reply	other threads:[~2008-08-17 11:31 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-31 13:55 [PATCH] Move assembly code out of the kernel chaac
2008-08-17 11:31 ` Vesa Jääskeläinen [this message]
2008-08-17 16:55   ` Bean
2008-08-24  9:37     ` Vesa Jääskeläinen
  -- strict thread matches above, loose matches on Subject: below --
2008-07-30 21:20 Bean
2008-07-31  7:46 ` Bean
2008-07-31 11:22   ` Robert Millan
2008-07-31 13:56     ` Bean

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48A80BF9.3090000@nic.fi \
    --to=chaac@nic.fi \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.