/*
* linux/drivers/video/vgacon.c -- Low level VGA based console driver
*
* Created 28 Sep 1997 by Geert Uytterhoeven
*
* Rewritten by Martin Mares <mj@ucw.cz>, July 1998
*
* This file is based on the old console.c, vga.c and vesa_blank.c drivers.
*
* Copyright (C) 1991, 1992 Linus Torvalds
* 1995 Jay Estabrook
*
* User definable mapping table and font loading by Eugene G. Crosser,
* <crosser@average.org>
*
* Improved loadable font/UTF-8 support by H. Peter Anvin
* Feb-Sep 1995 <peter.anvin@linux.org>
*
* Colour palette handling, by Simon Tatham
* 17-Jun-95 <sgt20@cam.ac.uk>
*
* if 512 char mode is already enabled don't re-enable it,
* because it causes screen to flicker, by Mitja Horvat
* 5-May-96 <mitja.horvat@guest.arnes.si>
*
* Use 2 outw instead of 4 outb_p to reduce erroneous text
* flashing on RHS of screen during heavy console scrolling .
* Oct 1996, Paul Gortmaker.
*
*
* 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.
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/console.h>
#include <linux/string.h>
#include <linux/kd.h>
#include <linux/slab.h>
#include <linux/vt_kern.h>
#include <linux/sched.h>
#include <linux/selection.h>
#include <linux/spinlock.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/screen_info.h>
#include <video/vga.h>
#include <asm/io.h>
static DEFINE_RAW_SPINLOCK(vga_lock);
static int cursor_size_lastfrom;
static int cursor_size_lastto;
static u32 vgacon_xres;
static u32 vgacon_yres;
static struct vgastate vgastate;
#define BLANK 0x0020
#define VGA_FONTWIDTH 8 /* VGA does not support fontwidths != 8 */
/*
* Interface used by the world
*/
static bool vgacon_set_origin(struct vc_data *c);
static struct uni_pagedict *vgacon_uni_pagedir;
static int vgacon_refcount;
/* Description of the hardware situation */
static unsigned long vga_vram_base __read_mostly; /* Base of video memory */
static unsigned long vga_vram_end __read_mostly; /* End of video memory */
static unsigned int vga_vram_size __read_mostly; /* Size of video memory */
static u16 vga_video_port_reg __read_mostly; /* Video register select port */
static u16 vga_video_port_val __read_mostly; /* Video register value port */
static unsigned int vga_video_num_columns; /* Number of text columns */
static unsigned int vga_video_num_lines; /* Number of text lines */
static bool vga_can_do_color; /* Do we support colors? */
static unsigned int vga_default_font_height __read_mostly; /* Height of default screen font */
static unsigned char vga_video_type __read_mostly; /* Card type */
static enum vesa_blank_mode vga_vesa_blanked;
static bool vga_palette_blanked;
static bool vga_is_gfx;
static bool vga_512_chars;
static int vga_video_font_height;
static int vga_scan_lines __read_mostly;
static unsigned int vga_rolled_over; /* last vc_origin offset before wrap */
static struct screen_info *vga_si;
static bool vga_hardscroll_enabled;
static bool vga_hardscroll_user_enable = true;
static int __init no_scroll(char *str)
{
/*
* Disabling scrollback is required for the Braillex ib80-piezo
* Braille reader made by F.H. Papenmeier (Germany).
* Use the "no-scroll" bootflag.
*/
vga_hardscroll_user_enable = vga_hardscroll_enabled = false;
return 1;
}
__setup("no-scroll", no_scroll);
/*
* By replacing the four outb_p with two back to back outw, we can reduce
* the window of opportunity to see text mislocated to the RHS of the
* console during heavy scrolling activity. However there is the remote
* possibility that some pre-dinosaur hardware won't like the back to back
* I/O. Since the Xservers get away with it, we should be able to as well.
*/
static inline void write_vga(unsigned char reg, unsigned int val)
{
unsigned int v1, v2;
unsigned long flags;
/*
* ddprintk might set the console position from interrupt
* handlers, thus the write has to be IRQ-atomic.
*/
raw_spin_lock_irqsave(&vga_lock, flags);
v1 = reg + (val & 0xff00);
v2 = reg + 1 + ((val << 8) & 0xff00);
outw(v1, vga_video_port_reg);
outw(v2, vga_video_port_reg);
raw_spin_unlock_irqrestore(&vga_lock, flags);
}
static inline void vga_set_mem_top(struct vc_data *c)
{
write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2);
}
static void vgacon_scrolldelta(struct vc_data *c, int lines)
{
unsigned long scr_end = c->vc_scr_end - vga_vram_base;
unsigned long vorigin = c->vc_visi