⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sticon-bmode.c

📁 linux下的VIDEO接口驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*TPG CVS users: please don't commit changes to this file directly, sendthem to prumpf@tux.org and wait for a new version instead.  Otherwise,your changes will get lost when prumpf releases the next version, asthis file *will* be replaced with it.  You have been warned.2000-05-30, <deller@gmx.de>*/#if 1#define DPRINTK(x)	printk x#else#define DPRINTK(x)#endif/* *  linux/drivers/video/sticon.c  - console driver using HP's STI firmware * *	Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> * *  Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c, *  which were * *	Created 28 Sep 1997 by Geert Uytterhoeven *	Rewritten by Martin Mares <mj@ucw.cz>, July 1998 *	Copyright (C) 1991, 1992  Linus Torvalds *			    1995  Jay Estabrook *	Copyright (C) 1995 Geert Uytterhoeven *	Copyright (C) 1993 Bjoern Brauel *			   Roman Hodek *	Copyright (C) 1993 Hamish Macdonald *			   Greg Harp *	Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk] * *	      with work by William Rucklidge (wjr@cs.cornell.edu) *			   Geert Uytterhoeven *			   Jes Sorensen (jds@kom.auc.dk) *			   Martin Apel *	      with work by Guenther Kelleter *			   Martin Schaller *			   Andreas Schwab *			   Emmanuel Marty (core@ggi-project.org) *			   Jakub Jelinek (jj@ultra.linux.cz) *			   Martin Mares <mj@ucw.cz> * *  This file is subject to the terms and conditions of the GNU General Public *  License.  See the file COPYING in the main directory of this archive for *  more details. *//* *  TODO: *   - call STI in virtual mode rather than in real mode *   - support for PCI-only STI ROMs (which don't have a traditional region *     list) *   - safe detection (i.e. verify there is a graphics device at a given *     address first, not just read a random device's io space) *   - support for multiple STI devices in one machine *   - support for byte-mode STI ROMs *   - support for just using STI to switch to a colour fb (stifb ?) *   - try to make it work on m68k hp workstations ;) */#include <linux/types.h>#include <linux/sched.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/tty.h>#include <linux/console.h>#include <linux/string.h>#include <linux/kd.h>#include <linux/slab.h>#include <linux/vt_kern.h>#include <linux/selection.h>#include <linux/ioport.h>#include <linux/init.h>#include <linux/delay.h>#include <asm/io.h>#include <asm/real.h>#include <linux/module.h>#include <linux/fb.h>#include <linux/smp.h>#include <asm/irq.h>#include <asm/system.h>#include <asm/uaccess.h>#include <video/fbcon.h>#include <video/font.h>#include "sti-bmode.h"/* The latency of the STI functions cannot really be reduced by setting * this to 0;  STI doesn't seem to be designed to allow calling a different * function (or the same function with different arguments) after a * function exited with 1 as return value. * * As all of the functions below could be called from interrupt context, * we have to spin_lock_irqsave around the do { ret = bla(); } while(ret==1) * block.  Really bad latency there. * * Probably the best solution to all this is have the generic code manage * the screen buffer and a kernel thread to call STI occasionally. *  * Luckily, the frame buffer guys have the same problem so we can just wait * for them to fix it and steal their solution.   prumpf * * Actually, another long-term viable solution is to completely do STI * support in userspace - that way we avoid the potential license issues * of using proprietary fonts, too. */ #define STI_WAIT 1#define STI_PTR(p) ( (typeof(p)) virt_to_phys(p))#define PTR_STI(p) ( (typeof(p)) phys_to_virt((unsigned long)p) )static struct sti_struct default_sti = {	SPIN_LOCK_UNLOCKED,};static struct sti_font_flags default_font_flags = {	STI_WAIT, 0, 0, NULL};/* The colour indices used by STI are *   0 - Black *   1 - White *   2 - Red *   3 - Yellow/Brown *   4 - Green *   5 - Cyan *   6 - Blue *   7 - Magenta * * So we have the same colours as VGA (basically one bit each for R, G, B), * but have to translate them, anyway. */static u8 col_trans[8] = {        0, 6, 4, 5,        2, 7, 3, 1};#define c_fg(sti, c) col_trans[((c>> 8) & 7)]#define c_bg(sti, c) col_trans[((c>>11) & 7)]#define c_index(sti, c) (c&0xff)#define sti_onscreen_x(sti) (PTR_STI(sti->glob_cfg)->onscreen_x)#define sti_onscreen_y(sti) (PTR_STI(sti->glob_cfg)->onscreen_y)#define sti_font_x(sti) (STI_U8(PTR_STI(sti->font)->width))#define sti_font_y(sti) (STI_U8(PTR_STI(sti->font)->height))static struct sti_init_flags default_init_flags = {	STI_WAIT, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, NULL};static void sti_init_graph(struct sti_struct *sti) {	struct sti_init_inptr_ext inptr_ext = {		0, { 0 }, 0, NULL	};	struct sti_init_inptr inptr = {		3, STI_PTR(&inptr_ext)	};	struct sti_init_outptr outptr = { 0 };	unsigned long flags;	s32 ret;	spin_lock_irqsave(&sti->lock, flags);	ret = STI_CALL(sti->init_graph, &default_init_flags, &inptr,		&outptr, sti->glob_cfg);	spin_unlock_irqrestore(&sti->lock, flags);	sti->text_planes = outptr.text_planes;}#if 0static struct sti_conf_flags default_conf_flags = {	STI_WAIT, 0, NULL};static void sti_inq_conf(struct sti_struct *sti){	struct sti_conf_inptr inptr = { NULL };	struct sti_conf_outptr_ext outptr_ext = { future_ptr: NULL };	struct sti_conf_outptr outptr = {		ext_ptr: STI_PTR(&outptr_ext)	};	unsigned long flags;	s32 ret;		do {		spin_lock_irqsave(&sti->lock, flags);		ret = STI_CALL(sti->inq_conf, &default_conf_flags,			&inptr, &outptr, sti->glob_cfg);		spin_unlock_irqrestore(&sti->lock, flags);	} while(ret == 1);}#endifstatic void sti_putc(struct sti_struct *sti, int c, int y, int x){	struct sti_font_inptr inptr = {		(u32) sti->font, c_index(sti, c), c_fg(sti, c), c_bg(sti, c),		x * sti_font_x(sti), y * sti_font_y(sti), NULL	};	struct sti_font_outptr outptr = {		0, NULL	};	s32 ret;	unsigned long flags;	do {		spin_lock_irqsave(&sti->lock, flags);		ret = STI_CALL(sti->font_unpmv, &default_font_flags,			&inptr, &outptr, sti->glob_cfg);		spin_unlock_irqrestore(&sti->lock, flags);	} while(ret == 1);}static struct sti_blkmv_flags clear_blkmv_flags = {	STI_WAIT, 1, 1, 0, 0, NULL};static void sti_set(struct sti_struct *sti, int src_y, int src_x,	int height, int width, u8 color){	struct sti_blkmv_inptr inptr = {		color, color,		src_x, src_y ,		src_x, src_y ,		width, height,		NULL	};	struct sti_blkmv_outptr outptr = { 0, NULL };	s32 ret = 0;	unsigned long flags;		do {		spin_lock_irqsave(&sti->lock, flags);		ret = STI_CALL(sti->block_move, &clear_blkmv_flags,			&inptr, &outptr, sti->glob_cfg);		spin_unlock_irqrestore(&sti->lock, flags);	} while(ret == 1);}static void sti_clear(struct sti_struct *sti, int src_y, int src_x,	int height, int width){	struct sti_blkmv_inptr inptr = {		0, 0,		src_x * sti_font_x(sti), src_y * sti_font_y(sti),		src_x * sti_font_x(sti), src_y * sti_font_y(sti),		width * sti_font_x(sti), height* sti_font_y(sti),		NULL	};	struct sti_blkmv_outptr outptr = { 0, NULL };	s32 ret = 0;	unsigned long flags;	do {		spin_lock_irqsave(&sti->lock, flags);		ret = STI_CALL(sti->block_move, &clear_blkmv_flags,			&inptr, &outptr, sti->glob_cfg);		spin_unlock_irqrestore(&sti->lock, flags);	} while(ret == 1);}static struct sti_blkmv_flags default_blkmv_flags = {	STI_WAIT, 0, 0, 0, 0, NULL};static void sti_bmove(struct sti_struct *sti, int src_y, int src_x,	int dst_y, int dst_x, int height, int width){	struct sti_blkmv_inptr inptr = {		0, 0,		src_x * sti_font_x(sti), src_y * sti_font_y(sti),		dst_x * sti_font_x(sti), dst_y * sti_font_y(sti),		width * sti_font_x(sti), height* sti_font_y(sti),		NULL	};	struct sti_blkmv_outptr outptr = { 0, NULL };	s32 ret = 0;	unsigned long flags;	do {		spin_lock_irqsave(&sti->lock, flags);		ret = STI_CALL(sti->block_move, &default_blkmv_flags,			&inptr, &outptr, sti->glob_cfg);		spin_unlock_irqrestore(&sti->lock, flags);	} while(ret == 1);}/* STICON */static const char __init *sticon_startup(void){	return "STI console";}static int sticon_set_palette(struct vc_data *c, unsigned char *table){	return -EINVAL;}static int sticon_font_op(struct vc_data *c, struct console_font_op *op){	return -ENOSYS;}static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos){	sti_putc(&default_sti, c, ypos, xpos);}static void sticon_putcs(struct vc_data *conp, const unsigned short *s,	int count, int ypos, int xpos){	while(count--) {		sti_putc(&default_sti, scr_readw(s++), ypos, xpos++);	}}static void sticon_cursor(struct vc_data *conp, int mode){}static int sticon_scroll(struct vc_data *conp, int t, int b, int dir,			int count){	struct sti_struct *sti = &default_sti;	if(console_blanked)		return 0;	sticon_cursor(conp, CM_ERASE);	switch(dir) {	case SM_UP:		sti_bmove(sti, t+count, 0, t, 0, b-t-count, conp->vc_cols);		sti_clear(sti, b-count, 0, count, conp->vc_cols);		break;	case SM_DOWN:		sti_bmove(sti, t, 0, t+count, 0, b-t-count, conp->vc_cols);		sti_clear(sti, t, 0, count, conp->vc_cols);		break;	}	return 0;}	static void sticon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,	int height, int width){	sti_bmove(&default_sti, sy, sx, dy, dx, height, width);}static void sticon_init(struct vc_data *c, int init){	struct sti_struct *sti = &default_sti;	int vc_cols, vc_rows;	sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0);	c->vc_can_do_color = 1;	vc_cols = PTR_STI(sti->glob_cfg)->onscreen_x / sti_font_x(sti);	vc_rows = PTR_STI(sti->glob_cfg)->onscreen_y / sti_font_y(sti);	vc_resize_con(vc_rows, vc_cols, c->vc_num);}static void sticon_deinit(struct vc_data *c){}static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,			int width){	sti_clear(&default_sti, sy, sx, height, width);}static int sticon_switch(struct vc_data *conp){	return 0;}static int sticon_blank(struct vc_data *conp, int blank){	return 0;}static int sticon_scrolldelta(struct vc_data *conp, int lines){	return 0;}static int sticon_set_origin(struct vc_data *conp){	return 0;}static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, u8 blink, u8 underline, u8 reverse){	u8 attr = ((color & 0x70) >> 1) | ((color & 7));	if(reverse) {		color = ((color>>3)&0x7) | ((color &0x7)<<3);	}	return attr;}static struct consw sti_con = {	con_startup: 		sticon_startup, 	con_init: 		sticon_init,	con_deinit: 		sticon_deinit,	con_clear: 		sticon_clear,	con_putc: 		sticon_putc,	con_putcs: 		sticon_putcs,	con_cursor: 		sticon_cursor,	con_scroll: 		sticon_scroll,	con_bmove: 		sticon_bmove,	con_switch: 		sticon_switch,	con_blank: 		sticon_blank,	con_font_op:		sticon_font_op,	con_set_palette:	sticon_set_palette,	con_scrolldelta:	sticon_scrolldelta,	con_set_origin: 	sticon_set_origin,	con_build_attr:		sticon_build_attr,};#include <asm/pgalloc.h>	/* need cache flush routines */static void __init sti_rom_copy(unsigned long base, unsigned long offset,				unsigned long count, void *dest){	void *savedest = dest;	int savecount = count;	while(count >= 4) {		count -= 4;		*(u32 *)dest = gsc_readl(base + offset);#if 0		DPRINTK(("%08x\n", *(u32 *)dest));		if(*(u32 *)dest == 0x64646464) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -