Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* -*- linux-c -*- ------------------------------------------------------- *
0003  *
0004  *   Copyright (C) 1991, 1992 Linus Torvalds
0005  *   Copyright 2007 rPath, Inc. - All Rights Reserved
0006  *   Copyright 2009 Intel Corporation; author H. Peter Anvin
0007  *
0008  * ----------------------------------------------------------------------- */
0009 
0010 /*
0011  * Standard video BIOS modes
0012  *
0013  * We have two options for this; silent and scanned.
0014  */
0015 
0016 #include "boot.h"
0017 #include "video.h"
0018 
0019 static __videocard video_bios;
0020 
0021 /* Set a conventional BIOS mode */
0022 static int set_bios_mode(u8 mode);
0023 
0024 static int bios_set_mode(struct mode_info *mi)
0025 {
0026     return set_bios_mode(mi->mode - VIDEO_FIRST_BIOS);
0027 }
0028 
0029 static int set_bios_mode(u8 mode)
0030 {
0031     struct biosregs ireg, oreg;
0032     u8 new_mode;
0033 
0034     initregs(&ireg);
0035     ireg.al = mode;     /* AH=0x00 Set Video Mode */
0036     intcall(0x10, &ireg, NULL);
0037 
0038     ireg.ah = 0x0f;     /* Get Current Video Mode */
0039     intcall(0x10, &ireg, &oreg);
0040 
0041     do_restore = 1;     /* Assume video contents were lost */
0042 
0043     /* Not all BIOSes are clean with the top bit */
0044     new_mode = oreg.al & 0x7f;
0045 
0046     if (new_mode == mode)
0047         return 0;   /* Mode change OK */
0048 
0049 #ifndef _WAKEUP
0050     if (new_mode != boot_params.screen_info.orig_video_mode) {
0051         /* Mode setting failed, but we didn't end up where we
0052            started.  That's bad.  Try to revert to the original
0053            video mode. */
0054         ireg.ax = boot_params.screen_info.orig_video_mode;
0055         intcall(0x10, &ireg, NULL);
0056     }
0057 #endif
0058     return -1;
0059 }
0060 
0061 static int bios_probe(void)
0062 {
0063     u8 mode;
0064 #ifdef _WAKEUP
0065     u8 saved_mode = 0x03;
0066 #else
0067     u8 saved_mode = boot_params.screen_info.orig_video_mode;
0068 #endif
0069     u16 crtc;
0070     struct mode_info *mi;
0071     int nmodes = 0;
0072 
0073     if (adapter != ADAPTER_EGA && adapter != ADAPTER_VGA)
0074         return 0;
0075 
0076     set_fs(0);
0077     crtc = vga_crtc();
0078 
0079     video_bios.modes = GET_HEAP(struct mode_info, 0);
0080 
0081     for (mode = 0x14; mode <= 0x7f; mode++) {
0082         if (!heap_free(sizeof(struct mode_info)))
0083             break;
0084 
0085         if (mode_defined(VIDEO_FIRST_BIOS+mode))
0086             continue;
0087 
0088         if (set_bios_mode(mode))
0089             continue;
0090 
0091         /* Try to verify that it's a text mode. */
0092 
0093         /* Attribute Controller: make graphics controller disabled */
0094         if (in_idx(0x3c0, 0x10) & 0x01)
0095             continue;
0096 
0097         /* Graphics Controller: verify Alpha addressing enabled */
0098         if (in_idx(0x3ce, 0x06) & 0x01)
0099             continue;
0100 
0101         /* CRTC cursor location low should be zero(?) */
0102         if (in_idx(crtc, 0x0f))
0103             continue;
0104 
0105         mi = GET_HEAP(struct mode_info, 1);
0106         mi->mode = VIDEO_FIRST_BIOS+mode;
0107         mi->depth = 0;  /* text */
0108         mi->x = rdfs16(0x44a);
0109         mi->y = rdfs8(0x484)+1;
0110         nmodes++;
0111     }
0112 
0113     set_bios_mode(saved_mode);
0114 
0115     return nmodes;
0116 }
0117 
0118 static __videocard video_bios =
0119 {
0120     .card_name  = "BIOS",
0121     .probe      = bios_probe,
0122     .set_mode   = bios_set_mode,
0123     .unsafe     = 1,
0124     .xmode_first    = VIDEO_FIRST_BIOS,
0125     .xmode_n    = 0x80,
0126 };