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  *   Original APM BIOS checking by Stephen Rothwell, May 1994
0009  *   (sfr@canb.auug.org.au)
0010  *
0011  * ----------------------------------------------------------------------- */
0012 
0013 /*
0014  * Get APM BIOS information
0015  */
0016 
0017 #include "boot.h"
0018 
0019 int query_apm_bios(void)
0020 {
0021     struct biosregs ireg, oreg;
0022 
0023     /* APM BIOS installation check */
0024     initregs(&ireg);
0025     ireg.ah = 0x53;
0026     intcall(0x15, &ireg, &oreg);
0027 
0028     if (oreg.flags & X86_EFLAGS_CF)
0029         return -1;      /* No APM BIOS */
0030 
0031     if (oreg.bx != 0x504d)      /* "PM" signature */
0032         return -1;
0033 
0034     if (!(oreg.cx & 0x02))      /* 32 bits supported? */
0035         return -1;
0036 
0037     /* Disconnect first, just in case */
0038     ireg.al = 0x04;
0039     intcall(0x15, &ireg, NULL);
0040 
0041     /* 32-bit connect */
0042     ireg.al = 0x03;
0043     intcall(0x15, &ireg, &oreg);
0044 
0045     boot_params.apm_bios_info.cseg        = oreg.ax;
0046     boot_params.apm_bios_info.offset      = oreg.ebx;
0047     boot_params.apm_bios_info.cseg_16     = oreg.cx;
0048     boot_params.apm_bios_info.dseg        = oreg.dx;
0049     boot_params.apm_bios_info.cseg_len    = oreg.si;
0050     boot_params.apm_bios_info.cseg_16_len = oreg.hsi;
0051     boot_params.apm_bios_info.dseg_len    = oreg.di;
0052 
0053     if (oreg.flags & X86_EFLAGS_CF)
0054         return -1;
0055 
0056     /* Redo the installation check as the 32-bit connect;
0057        some BIOSes return different flags this way... */
0058 
0059     ireg.al = 0x00;
0060     intcall(0x15, &ireg, &oreg);
0061 
0062     if ((oreg.eflags & X86_EFLAGS_CF) || oreg.bx != 0x504d) {
0063         /* Failure with 32-bit connect, try to disconnect and ignore */
0064         ireg.al = 0x04;
0065         intcall(0x15, &ireg, NULL);
0066         return -1;
0067     }
0068 
0069     boot_params.apm_bios_info.version = oreg.ax;
0070     boot_params.apm_bios_info.flags   = oreg.cx;
0071     return 0;
0072 }
0073