cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

video-bios.c (2766B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* -*- linux-c -*- ------------------------------------------------------- *
      3 *
      4 *   Copyright (C) 1991, 1992 Linus Torvalds
      5 *   Copyright 2007 rPath, Inc. - All Rights Reserved
      6 *   Copyright 2009 Intel Corporation; author H. Peter Anvin
      7 *
      8 * ----------------------------------------------------------------------- */
      9
     10/*
     11 * Standard video BIOS modes
     12 *
     13 * We have two options for this; silent and scanned.
     14 */
     15
     16#include "boot.h"
     17#include "video.h"
     18
     19static __videocard video_bios;
     20
     21/* Set a conventional BIOS mode */
     22static int set_bios_mode(u8 mode);
     23
     24static int bios_set_mode(struct mode_info *mi)
     25{
     26	return set_bios_mode(mi->mode - VIDEO_FIRST_BIOS);
     27}
     28
     29static int set_bios_mode(u8 mode)
     30{
     31	struct biosregs ireg, oreg;
     32	u8 new_mode;
     33
     34	initregs(&ireg);
     35	ireg.al = mode;		/* AH=0x00 Set Video Mode */
     36	intcall(0x10, &ireg, NULL);
     37
     38	ireg.ah = 0x0f;		/* Get Current Video Mode */
     39	intcall(0x10, &ireg, &oreg);
     40
     41	do_restore = 1;		/* Assume video contents were lost */
     42
     43	/* Not all BIOSes are clean with the top bit */
     44	new_mode = oreg.al & 0x7f;
     45
     46	if (new_mode == mode)
     47		return 0;	/* Mode change OK */
     48
     49#ifndef _WAKEUP
     50	if (new_mode != boot_params.screen_info.orig_video_mode) {
     51		/* Mode setting failed, but we didn't end up where we
     52		   started.  That's bad.  Try to revert to the original
     53		   video mode. */
     54		ireg.ax = boot_params.screen_info.orig_video_mode;
     55		intcall(0x10, &ireg, NULL);
     56	}
     57#endif
     58	return -1;
     59}
     60
     61static int bios_probe(void)
     62{
     63	u8 mode;
     64#ifdef _WAKEUP
     65	u8 saved_mode = 0x03;
     66#else
     67	u8 saved_mode = boot_params.screen_info.orig_video_mode;
     68#endif
     69	u16 crtc;
     70	struct mode_info *mi;
     71	int nmodes = 0;
     72
     73	if (adapter != ADAPTER_EGA && adapter != ADAPTER_VGA)
     74		return 0;
     75
     76	set_fs(0);
     77	crtc = vga_crtc();
     78
     79	video_bios.modes = GET_HEAP(struct mode_info, 0);
     80
     81	for (mode = 0x14; mode <= 0x7f; mode++) {
     82		if (!heap_free(sizeof(struct mode_info)))
     83			break;
     84
     85		if (mode_defined(VIDEO_FIRST_BIOS+mode))
     86			continue;
     87
     88		if (set_bios_mode(mode))
     89			continue;
     90
     91		/* Try to verify that it's a text mode. */
     92
     93		/* Attribute Controller: make graphics controller disabled */
     94		if (in_idx(0x3c0, 0x10) & 0x01)
     95			continue;
     96
     97		/* Graphics Controller: verify Alpha addressing enabled */
     98		if (in_idx(0x3ce, 0x06) & 0x01)
     99			continue;
    100
    101		/* CRTC cursor location low should be zero(?) */
    102		if (in_idx(crtc, 0x0f))
    103			continue;
    104
    105		mi = GET_HEAP(struct mode_info, 1);
    106		mi->mode = VIDEO_FIRST_BIOS+mode;
    107		mi->depth = 0;	/* text */
    108		mi->x = rdfs16(0x44a);
    109		mi->y = rdfs8(0x484)+1;
    110		nmodes++;
    111	}
    112
    113	set_bios_mode(saved_mode);
    114
    115	return nmodes;
    116}
    117
    118static __videocard video_bios =
    119{
    120	.card_name	= "BIOS",
    121	.probe		= bios_probe,
    122	.set_mode	= bios_set_mode,
    123	.unsafe		= 1,
    124	.xmode_first	= VIDEO_FIRST_BIOS,
    125	.xmode_n	= 0x80,
    126};