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

📄 console.c

📁 newos is new operation system
💻 C
字号:
#include <kernel/mod_console.h>#include <kernel/vm.h>#include <kernel/module.h>#include <newos/errors.h>#include <kernel/bus/pci/pci.h>#include "svga_reg.h"#include "vm_device_version.h"#include "font.h"static struct {	addr_t		fb_base;	addr_t		fb_phys_base;	addr_t		fb_size;	addr_t		fifo_base;	addr_t		fifo_phys_base;	addr_t		fifo_size;	uint32		scrn_width;	uint32		scrn_height;	uint32		fb_offset;	uint32		bytes_per_line;	uint32		bits_per_pixel;	uint32		red_mask;	uint32		blue_mask;	uint32		green_mask;	int32		cursor_x;	int32		cursor_y;	int32		text_rows;	int32		text_cols;	uint32		glyph_width;	uint32		glyph_height;	uint32		fg, bg;	uint32		txt_off_x, txt_off_y;	int32		cursor_visible;	region_id	fb_region;	region_id	fifo_region;	uint16		index_port;	uint16		value_port;} vcons;static uint8 bit_reversed[256];static void show_cursor(int show);static void setup_bit_reversed(void);static void write_glyph(char c, uint32 x, uint32 y, uint32 fg, uint32 bg);static int set_mode(uint32 width, uint32 height);static void load_font();static int find_and_map(void);void out_reg(uint32 index, uint32 value);uint32 in_reg(uint32 index);static void init_fifo();static void writeFIFO(uint32 value);static void clear_screen();static void fill_rect(uint32 color, uint32 x, uint32 y, uint32 width, uint32 height);static void copy_rect(uint32 src_x, uint32 src_y, uint32 dst_x, uint32 dst_y, uint32 width, uint32 height);static void invert_rect(uint32 x, uint32 y, uint32 width, uint32 height);static void define_font(uint32 id, uint32 width, uint32 height, uint8 *bits);static void copy_bitmap(uint32 id, uint32 src_x, uint32 src_y, uint32 dst_x, uint32 dst_y, uint32 width, uint32 height, uint32 fg, uint32 bg);#define MIN(a, b) ((a)<(b)?(a):(b))void out_reg(uint32 index, uint32 value){	out32(index, vcons.index_port);	out32(value, vcons.value_port);}uint32 in_reg(uint32 index){	out32(index, vcons.index_port);	return in32(vcons.value_port);}static void define_font(uint32 id, uint32 width, uint32 height, uint8 *bits){	dprintf("define_font(%u, %u,%u, %p)\n", id, width, height, bits);	writeFIFO(SVGA_CMD_DEFINE_BITMAP);	writeFIFO(id);	writeFIFO(width);	writeFIFO(height);	while (height--) writeFIFO(bit_reversed[*bits++]);}static void copy_bitmap(uint32 id, uint32 src_x, uint32 src_y, uint32 dst_x, uint32 dst_y, uint32 width, uint32 height, uint32 fg, uint32 bg){	writeFIFO(SVGA_CMD_RECT_BITMAP_COPY);	writeFIFO(id);	writeFIFO(src_x);	writeFIFO(src_y);	writeFIFO(dst_x);	writeFIFO(dst_y);	writeFIFO(width);	writeFIFO(height);	writeFIFO(fg);	writeFIFO(bg);}static void write_glyph(char c, uint32 x, uint32 y, uint32 fg, uint32 bg){	copy_bitmap(1, 0, vcons.glyph_height * (int)c, (x * vcons.glyph_width) + vcons.txt_off_x, (y * vcons.glyph_height) + vcons.txt_off_y, vcons.glyph_width, vcons.glyph_height, fg, bg);}static void load_font(){	vcons.glyph_width = CHAR_WIDTH;	vcons.glyph_height = CHAR_HEIGHT;	vcons.text_cols = vcons.scrn_width / vcons.glyph_width;	vcons.text_rows = vcons.scrn_height / vcons.glyph_height;	// center the text display, giving any extra pixels to the left/bottom	vcons.txt_off_x = ((vcons.scrn_width - (vcons.text_cols * vcons.glyph_width)) + 1) / 2;	vcons.txt_off_y = ((vcons.scrn_height - (vcons.text_rows * vcons.glyph_height)) + 0) / 2;	define_font(1, ((CHAR_WIDTH + 7) & ~7), sizeof(FONT), FONT);	dprintf("load_font: %dx%d glyphs\n", vcons.text_cols, vcons.text_rows);}static int set_mode(uint32 width, uint32 height){	out_reg(SVGA_REG_WIDTH, width);	out_reg(SVGA_REG_HEIGHT, height);	vcons.fb_offset = in_reg(SVGA_REG_FB_OFFSET);	vcons.bytes_per_line = in_reg(SVGA_REG_BYTES_PER_LINE);	vcons.red_mask = in_reg(SVGA_REG_RED_MASK);	vcons.green_mask = in_reg(SVGA_REG_GREEN_MASK);	vcons.blue_mask = in_reg(SVGA_REG_BLUE_MASK);	out_reg(SVGA_REG_ENABLE, 1);	vcons.scrn_width = width;	vcons.scrn_height = height;	return 0;}static int find_and_map(void){	int err;	pci_module_hooks *pci;	pci_info pinfo;	aspace_id kai = vm_get_kernel_aspace_id();	int i;	bool foundit;	if(module_get(PCI_BUS_MODULE_NAME, 0, (void **)&pci) < 0) {		dprintf("vmware: no pci bus found..\n");		err = ERR_NOT_FOUND;		goto error0;	}	foundit = false;	for(i = 0; pci->get_nth_pci_info(i, &pinfo) >= NO_ERROR; i++) {		dprintf("vmware: looking at 0x%x:0x%x\n", pinfo.vendor_id, pinfo.device_id);		if(pinfo.vendor_id == PCI_VENDOR_ID_VMWARE &&			(pinfo.device_id == PCI_DEVICE_ID_VMWARE_SVGA2 || pinfo.device_id == PCI_DEVICE_ID_VMWARE_SVGA)) {			foundit = true;			break;		}	}	if(!foundit) {		dprintf("vmware: didn't find device on pci bus\n");		err = ERR_NOT_FOUND;		goto error0;	}	switch(pinfo.device_id) {		case PCI_DEVICE_ID_VMWARE_SVGA:			dprintf("vmware SVGA device detected at pci %d:%d:%d\n", pinfo.bus, pinfo.device, pinfo.function);			vcons.index_port = SVGA_LEGACY_BASE_PORT + SVGA_INDEX_PORT * 4;			vcons.value_port = SVGA_LEGACY_BASE_PORT + SVGA_VALUE_PORT * 4;			break;		case PCI_DEVICE_ID_VMWARE_SVGA2:			dprintf("vmware SVGA2 device detected at pci %d:%d:%d\n", pinfo.bus, pinfo.device, pinfo.function);			vcons.index_port = pinfo.u.h0.base_registers[0] + SVGA_INDEX_PORT;			vcons.value_port = pinfo.u.h0.base_registers[0] + SVGA_VALUE_PORT;			break;	}	vcons.fb_phys_base = pinfo.u.h0.base_registers[1];	vcons.fb_size = MIN(pinfo.u.h0.base_register_sizes[1], SVGA_FB_MAX_SIZE);	vcons.fifo_phys_base = pinfo.u.h0.base_registers[2];	vcons.fifo_size = MIN(pinfo.u.h0.base_register_sizes[2], SVGA_MEM_SIZE);	dprintf("vmware: phys base 0x%x, size 0x%X\n", vcons.fb_phys_base, vcons.fb_size);	dprintf("vmware: fifo phys base 0x%x, fifo size 0x%X\n", vcons.fifo_phys_base, vcons.fifo_size);	vcons.fb_region = vm_map_physical_memory(kai, "vmw:fb", (void **)&vcons.fb_base, REGION_ADDR_ANY_ADDRESS, vcons.fb_size, LOCK_KERNEL | LOCK_RW, vcons.fb_phys_base);	if (vcons.fb_region < 0)	{		err = vcons.fb_region;		dprintf("Error mapping frame buffer: %x\n", err);		goto error0;	}	vcons.fifo_region = vm_map_physical_memory(kai, "vmw:fifo", (void **)&vcons.fifo_base, REGION_ADDR_ANY_ADDRESS, vcons.fifo_size, LOCK_KERNEL | LOCK_RW, vcons.fifo_phys_base);	if (vcons.fifo_region < 0)	{		err = vcons.fifo_region;		dprintf("Error mapping vmw::fifo: %x\n", err);		goto error1;	}	out_reg(SVGA_REG_ID, SVGA_ID_2);	vcons.bits_per_pixel = in_reg(SVGA_REG_BITS_PER_PIXEL);	err = NO_ERROR;	goto error0;	// unmap vcons.fifo_region	vm_delete_region(kai, vcons.fifo_region);error1:	// unmap vcons.fb_region	vm_delete_region(kai, vcons.fb_region);error0:	return err;}static void setup_bit_reversed(void){	uint8 val, rev;	int i, j;	for (i = 0; i < 256; i++)	{		val = i;		rev = 0;		for (j = 0; j < 8; j++)		{			rev <<= 1;			if (val & 1) rev |= 1;			val >>= 1;		}		bit_reversed[i] = rev;	}}static void init_fifo(){	uint32* vmwareFIFO = (uint32*)vcons.fifo_base;	vmwareFIFO[SVGA_FIFO_MIN] = 16;	vmwareFIFO[SVGA_FIFO_MAX] = vcons.fifo_size;	vmwareFIFO[SVGA_FIFO_NEXT_CMD] = 16;	vmwareFIFO[SVGA_FIFO_STOP] = 16;	out_reg(SVGA_REG_CONFIG_DONE, 1);}static voidwriteFIFO(uint32 value){	uint32* vmwareFIFO = (uint32*)vcons.fifo_base;	/* Need to sync? */	if ((vmwareFIFO[SVGA_FIFO_NEXT_CMD] + sizeof(uint32) == vmwareFIFO[SVGA_FIFO_STOP])		|| (vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32) &&		vmwareFIFO[SVGA_FIFO_STOP] == vmwareFIFO[SVGA_FIFO_MIN]))	{		out_reg(SVGA_REG_SYNC, 1);		while (in_reg(SVGA_REG_BUSY)) ;	}	vmwareFIFO[vmwareFIFO[SVGA_FIFO_NEXT_CMD] / sizeof(uint32)] = value;	vmwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof(uint32);	if (vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX])	{		vmwareFIFO[SVGA_FIFO_NEXT_CMD] = vmwareFIFO[SVGA_FIFO_MIN];	}}static void clear_screen(){	fill_rect(vcons.bg, 0, 0, vcons.scrn_width, vcons.scrn_height);}static void invert_rect(uint32 x, uint32 y, uint32 width, uint32 height){#define GXinvert 0xa	writeFIFO(SVGA_CMD_RECT_ROP_FILL);	writeFIFO(0); // color	writeFIFO(x);	writeFIFO(y);	writeFIFO(width);	writeFIFO(height);	writeFIFO(GXinvert);}static void show_cursor(int show){	show = show != 0;	if (show == vcons.cursor_visible) return;	vcons.cursor_visible = show;	invert_rect((vcons.cursor_x * vcons.glyph_width) + vcons.txt_off_x, (vcons.cursor_y * vcons.glyph_height) + vcons.txt_off_y, vcons.glyph_width, vcons.glyph_height);}static void copy_rect(uint32 src_x, uint32 src_y, uint32 dst_x, uint32 dst_y, uint32 width, uint32 height){	writeFIFO(SVGA_CMD_RECT_COPY);	writeFIFO(src_x);	writeFIFO(src_y);	writeFIFO(dst_x);	writeFIFO(dst_y);	writeFIFO(width);	writeFIFO(height);}static void fill_rect(uint32 color, uint32 x, uint32 y, uint32 width, uint32 height){	writeFIFO(SVGA_CMD_RECT_FILL);	writeFIFO(color);	writeFIFO(x);	writeFIFO(y);	writeFIFO(width);	writeFIFO(height);	//dprintf("fill_rect(%6x,%u,%u,%u,%u)\n", color, x, y, width, height);}uint32 colors32[16] = {	0x00000000, 	// 0 - black	0x0000007f, 	// 1 - blue	0x00007f00, 	// 2 - green	0x00007f7f, 	// 3 - cyan	0x007f0000, 	// 4 - red	0x007f007f, 	// 5 - magenta	0x007f7f00, 	// 6 - yellow	0x007f7f7f, 	// 7 - white (aka grey)	0x00000000, 	// 8 - bright? black	0x000000ff, 	// 9 - bright blue	0x0000ff00, 	// a - bright green	0x0000ffff, 	// b - bright cyan	0x00ff0000, 	// c - bright red	0x00ff00ff, 	// d - bright magenta	0x00ffff00, 	// e - bright yellow	0x00ffffff	 	// f - bright? white};uint32 colors16[16];uint32 *colors;static void colors_from_attr(uint8 attr, uint32 *fg, uint32 *bg){#define FMASK 0x0f#define BMASK 0xf0	*fg = colors[attr & FMASK];	*bg = colors[(attr & BMASK) >> 4];#undef FMASK#undef BMASK}static int log2(uint32 v){	static int table[16] = {		0xfffffff,		0,		1, 1,		2, 2, 2, 2,		3, 3, 3, 3, 3, 3, 3, 3	};	int result = 0;	dprintf("log2(%8x)", v);	if ((v & 0xffff) == 0) { result += 16; v >>= 16; }	if ((v & 0xff) == 0) { result += 8; v >>= 8; }	if ((v & 0xf) == 0) { result += 4; v >>= 4; }	result += table[v];	dprintf(": %d\n", result);	return result;}static void setup_color_table(void){	if (vcons.bits_per_pixel > 16)	{		colors = colors32;	}	else	{		int index;		int red_shift, blue_shift, green_shift;		blue_shift = 8 - log2(vcons.blue_mask + (vcons.blue_mask & ~(vcons.blue_mask - 1)));		green_shift = 16 - log2(vcons.green_mask + (vcons.green_mask & ~(vcons.green_mask - 1)));		red_shift = 24 - log2(vcons.red_mask + (vcons.red_mask & ~(vcons.red_mask - 1)));		dprintf("r: %d, g: %d, b: %d\n", red_shift, green_shift, blue_shift);		for (index = 0; index < 16; index++)		{			uint32 base = colors32[index];			colors16[index] =				((base >> red_shift) & vcons.red_mask) |				((base >> green_shift) & vcons.green_mask) |				((base >> blue_shift) & vcons.blue_mask) ;		}		colors = colors16;	}}static int vmware_init(void){	int err = find_and_map();	if (!err)	{		vcons.cursor_visible = 0;		vcons.bg = 0;		vcons.fg = 0xffffff;		setup_bit_reversed();		init_fifo();		set_mode(132 * CHAR_WIDTH + 4, 50 * CHAR_HEIGHT + 4);		setup_color_table();		clear_screen();		dprintf("screen cleared\n");		load_font();		dprintf("font loaded\n");	}	return err;}static int vmware_uninit(void){	// unmap video memory (someday)	return 0;}static int get_size(int *width, int *height){	*width = vcons.text_cols;	*height = vcons.text_rows;	return 0;}static int move_cursor(int x, int y){	// hide the cursor before we move it	show_cursor(0);	if ((x >= 0) && (y >= 0))	{		// update cursor location		vcons.cursor_x = x;		vcons.cursor_y = y;		// show the cursor		show_cursor(1);	}	return 0;}static int put_glyph(int x, int y, uint8 glyph, uint8 attr){	uint32 fg, bg;	colors_from_attr(attr, &fg, &bg);	write_glyph(glyph, x, y, fg, bg);	return 0;}static int fill_glyph(int x, int y, int width, int height, uint8 glyph, uint8 attr){	uint32 fg, bg;	int xi, yi;	int x_lim = x + width;	int y_lim = y + height;	colors_from_attr(attr, &fg, &bg);	// FIXME: see if we can't make vmware tile the bitmap for us	for (yi = y; yi < y_lim; yi++)		for (xi = x; xi < x_lim; xi++)			write_glyph(glyph, xi, yi, fg, bg);	return 0;}static int blt(int srcx, int srcy, int width, int height, int destx, int desty){	uint32 pix_srcx = vcons.txt_off_x + (vcons.glyph_width * srcx);	uint32 pix_srcy = vcons.txt_off_y + (vcons.glyph_height* srcy);	uint32 pix_dstx = vcons.txt_off_x + (vcons.glyph_width * destx);	uint32 pix_dsty = vcons.txt_off_y + (vcons.glyph_height* desty);	copy_rect(pix_srcx, pix_srcy, pix_dstx, pix_dsty, width * vcons.glyph_width, height * vcons.glyph_height);	return 0;}static mod_console vmware_mod_console = {	get_size,	move_cursor,	put_glyph,	fill_glyph,	blt};static module_header vmware_module_header = {	"console/vmware/v1",	MODULE_CURR_VERSION,	0,	(void*) &vmware_mod_console,	vmware_init,	vmware_uninit};module_header *modules[] = {	&vmware_module_header,	0};

⌨️ 快捷键说明

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