Re: [PATCH 1/5 V2] kvm tools: Add BIOS INT10 handler

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



* Sasha Levin <levinsasha928@xxxxxxxxx> wrote:

> INT10 handler is a basic implementation of BIOS video services.
> 
> The handler implements a VESA interface which is initialized at
> the very beginning of loading the kernel.
> 
> Signed-off-by: John Floren <john@xxxxxxxxxxx>
> [ turning code into patches and cleanup ]
> Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx>
> ---
>  tools/kvm/bios/bios-rom.S |   56 ++++++++--------
>  tools/kvm/bios/int10.c    |  161 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 189 insertions(+), 28 deletions(-)
>  create mode 100644 tools/kvm/bios/int10.c
> 
> diff --git a/tools/kvm/bios/bios-rom.S b/tools/kvm/bios/bios-rom.S
> index 8a53dcd..b636cb8 100644
> --- a/tools/kvm/bios/bios-rom.S
> +++ b/tools/kvm/bios/bios-rom.S
> @@ -27,36 +27,36 @@ ENTRY_END(bios_intfake)
>   * We ignore bx settings
>   */
>  ENTRY(bios_int10)
> -	test $0x0e, %ah
> -	jne 1f
> +	pushw	%fs
> +	pushl	%es
> +	pushl	%edi
> +	pushl	%esi
> +	pushl	%ebp
> +	pushl	%esp
> +	pushl	%edx
> +	pushl	%ecx
> +	pushl	%ebx
> +	pushl	%eax
> +
> +	movl		%esp, %eax
> +	/* this is way easier than doing it in assembly */
> +	/* just push all the regs and jump to a C handler */
> +	call	int10handler
> +
> +	popl	%eax
> +	popl	%ebx
> +	popl	%ecx
> +	popl	%edx
> +	popl	%esp
> +	popl	%ebp
> +	popl	%esi
> +	popl	%edi
> +	popl	%es
> +	popw	%fs
>  
> -/*
> - * put char in AL at current cursor and
> - * increment cursor position
> - */
> -putchar:
> -	stack_swap
> -
> -	push %fs
> -	push %bx
> -
> -	mov $VGA_RAM_SEG, %bx
> -	mov %bx, %fs
> -	mov %cs:(cursor), %bx
> -	mov %al, %fs:(%bx)
> -	inc %bx
> -	test $VGA_PAGE_SIZE, %bx
> -	jb putchar_new
> -	xor %bx, %bx
> -putchar_new:
> -	mov %bx, %fs:(cursor)
> -
> -	pop %bx
> -	pop %fs
> -
> -	stack_restore
> -1:
>  	IRET
> +
> +
>  /*
>   * private IRQ data
>   */
> diff --git a/tools/kvm/bios/int10.c b/tools/kvm/bios/int10.c
> new file mode 100644
> index 0000000..98205c3
> --- /dev/null
> +++ b/tools/kvm/bios/int10.c
> @@ -0,0 +1,161 @@
> +#include "kvm/segment.h"
> +#include "kvm/bios.h"
> +#include "kvm/util.h"
> +#include "kvm/vesa.h"
> +#include <stdint.h>
> +
> +#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
> +
> +struct int10args {
> +	u32	eax;
> +	u32	ebx;
> +	u32	ecx;
> +	u32	edx;
> +	u32	esp;
> +	u32	ebp;
> +	u32	esi;
> +	u32	edi;
> +	u32	es;
> +};
> +
> +/* VESA General Information table */
> +struct vesa_general_info {
> +	u32 signature;			/* 0 Magic number = "VESA" */
> +	u16 version;			/* 4 */
> +	void *vendor_string;		/* 6 */
> +	u32 capabilities;		/* 10 */
> +	void *video_mode_ptr;		/* 14 */
> +	u16 total_memory;		/* 18 */
> +
> +	u8 reserved[236];		/* 20 */
> +} __attribute__ ((packed));
> +
> +
> +struct vminfo {
> +	u16	mode_attr;		/* 0 */
> +	u8	win_attr[2];		/* 2 */
> +	u16	win_grain;		/* 4 */
> +	u16	win_size;		/* 6 */
> +	u16	win_seg[2];		/* 8 */
> +	u32	win_scheme;		/* 12 */
> +	u16	logical_scan;		/* 16 */
> +
> +	u16	h_res;			/* 18 */
> +	u16	v_res;			/* 20 */
> +	u8	char_width;		/* 22 */
> +	u8	char_height;		/* 23 */
> +	u8	memory_planes;		/* 24 */
> +	u8	bpp;			/* 25 */
> +	u8	banks;			/* 26 */
> +	u8	memory_layout;		/* 27 */
> +	u8	bank_size;		/* 28 */
> +	u8	image_planes;		/* 29 */
> +	u8	page_function;		/* 30 */
> +
> +	u8	rmask;			/* 31 */
> +	u8	rpos;			/* 32 */
> +	u8	gmask;			/* 33 */
> +	u8	gpos;			/* 34 */
> +	u8	bmask;			/* 35 */
> +	u8	bpos;			/* 36 */
> +	u8	resv_mask;		/* 37 */
> +	u8	resv_pos;		/* 38 */
> +	u8	dcm_info;		/* 39 */
> +
> +	u32	lfb_ptr;		/* 40 Linear frame buffer address */
> +	u32	offscreen_ptr;		/* 44 Offscreen memory address */
> +	u16	offscreen_size;		/* 48 */
> +
> +	u8	reserved[206];		/* 50 */
> +};
> +
> +char oemstring[11] = "KVM VESA";
> +u16 modes[2] = { 0x0112, 0xffff };
> +
> +static inline void outb(unsigned short port, unsigned char val)
> +{
> +	asm volatile("outb %0, %1" : : "a"(val), "Nd"(port));
> +}
> +
> +/*
> + * It's probably much more useful to make this print to the serial
> + * line rather than print to a non-displayed VGA memory
> + */
> +static inline void int10putchar(struct int10args *args)
> +{
> +	u8 al, ah;
> +
> +	al = args->eax & 0xFF;
> +	ah = (args->eax & 0xFF00) >> 8;
> +
> +	outb(0x3f8, al);
> +}
> +
> +static void int10vesa(struct int10args *args)
> +{
> +	u8 al, ah;
> +	struct vesa_general_info *destination;
> +	struct vminfo *vi;
> +
> +	al = args->eax;
> +	ah = args->eax >> 8;
> +
> +	switch (al) {
> +	case 0:
> +		/* Set controller info */
> +
> +		destination = (struct vesa_general_info *)args->edi;
> +		*destination = (struct vesa_general_info) {
> +			.signature	= VESA_MAGIC,
> +			.version	= 0x102,
> +			.vendor_string	= oemstring,
> +			.capabilities	= 0x10,
> +			.video_mode_ptr	= modes,
> +			.total_memory	= (4*VESA_WIDTH * VESA_HEIGHT) / 0x10000,
> +		};
> +
> +		break;
> +	case 1:
> +		vi = (struct vminfo *)args->edi;
> +		*vi = (struct vminfo) {
> +			.mode_attr	= 0xd9, /* 11011011 */
> +			.logical_scan	= VESA_WIDTH*4,
> +			.h_res		= VESA_WIDTH,
> +			.v_res		= VESA_HEIGHT,
> +			.bpp		= VESA_BPP,
> +			.memory_layout	= 6,
> +			.memory_planes	= 1,
> +			.lfb_ptr	= VESA_MEM_ADDR,
> +			.rmask		= 8,
> +			.gmask		= 8,
> +			.bmask		= 8,
> +			.resv_mask	= 8,
> +			.resv_pos	= 24,
> +			.bpos		= 16,
> +			.gpos		= 8,
> +		};
> +
> +		break;
> +	}
> +
> +	args->eax			= 0x004f; /* return success every time */
> +
> +}
> +
> +bioscall void int10handler(struct int10args *args)
> +{
> +	u8 ah;
> +
> +	ah = (args->eax & 0xff00) >> 8;
> +
> +	switch (ah) {
> +	case 0x0e:
> +		int10putchar(args);
> +		break;
> +	case 0x4f:
> +		int10vesa(args);
> +		break;
> +	}

Why are these functions prefixed in such a weird way? Why not int10_putchar(), 
int10_vesa(), etc. like all other bits in tools/kvm/?

Thanks,

	Ingo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux