Implement APM
This commit is contained in:
parent
e31bb61911
commit
890c9fa5f2
10 changed files with 257 additions and 5 deletions
|
@ -1433,3 +1433,9 @@ module = {
|
|||
name = testload;
|
||||
common = commands/testload.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = lsapm;
|
||||
common = commands/i386/pc/lsapm.c;
|
||||
enable = i386_pc;
|
||||
};
|
||||
|
|
113
grub-core/commands/i386/pc/lsapm.c
Normal file
113
grub-core/commands/i386/pc/lsapm.c
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/machine/int.h>
|
||||
#include <grub/machine/apm.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
int
|
||||
grub_apm_get_info (struct grub_apm_info *info)
|
||||
{
|
||||
struct grub_bios_int_registers regs;
|
||||
|
||||
/* detect APM */
|
||||
regs.eax = 0x5300;
|
||||
regs.ebx = 0;
|
||||
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||
grub_bios_interrupt (0x15, ®s);
|
||||
|
||||
if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
|
||||
return 0;
|
||||
info->version = regs.eax & 0xffff;
|
||||
info->flags = regs.ecx & 0xffff;
|
||||
|
||||
/* disconnect APM first */
|
||||
regs.eax = 0x5304;
|
||||
regs.ebx = 0;
|
||||
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||
grub_bios_interrupt (0x15, ®s);
|
||||
|
||||
/* connect APM */
|
||||
regs.eax = 0x5303;
|
||||
regs.ebx = 0;
|
||||
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||
grub_bios_interrupt (0x15, ®s);
|
||||
|
||||
if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
|
||||
return 0;
|
||||
|
||||
info->cseg = regs.eax & 0xffff;
|
||||
info->offset = regs.ebx;
|
||||
info->cseg_16 = regs.ecx & 0xffff;
|
||||
info->dseg = regs.edx & 0xffff;
|
||||
info->cseg_len = regs.esi >> 16;
|
||||
info->cseg_16_len = regs.esi & 0xffff;
|
||||
info->dseg_len = regs.edi;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_lsapm (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)), char **args __attribute__ ((unused)))
|
||||
{
|
||||
struct grub_apm_info info;
|
||||
if (!grub_apm_get_info (&info))
|
||||
return grub_error (GRUB_ERR_IO, "no APM found");
|
||||
|
||||
grub_printf ("Vesion %u.%u\n"
|
||||
"32-bit CS = 0x%x, len = 0x%x, offset = 0x%x\n"
|
||||
"16-bit CS = 0x%x, len = 0x%x\n"
|
||||
"DS = 0x%x, len = 0x%x\n",
|
||||
info.version >> 8, info.version & 0xff,
|
||||
info.cseg, info.cseg_len, info.offset,
|
||||
info.cseg_16, info.cseg_16_len,
|
||||
info.dseg, info.dseg_len);
|
||||
grub_xputs (info.flags & GRUB_APM_FLAGS_16BITPROTECTED_SUPPORTED
|
||||
? "16-bit protected interface supported\n"
|
||||
: "16-bit protected interface unsupported\n");
|
||||
grub_xputs (info.flags & GRUB_APM_FLAGS_32BITPROTECTED_SUPPORTED
|
||||
? "32-bit protected interface supported\n"
|
||||
: "32-bit protected interface unsupported\n");
|
||||
grub_xputs (info.flags & GRUB_APM_FLAGS_CPUIDLE_SLOWS_DOWN
|
||||
? "CPU Idle slows down processor\n"
|
||||
: "CPU Idle doesn't slow down processor\n");
|
||||
grub_xputs (info.flags & GRUB_APM_FLAGS_DISABLED
|
||||
? "APM disabled\n" : "APM enabled\n");
|
||||
grub_xputs (info.flags & GRUB_APM_FLAGS_DISENGAGED
|
||||
? "APM disengaged\n" : "APM engaged\n");
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(lsapm)
|
||||
{
|
||||
cmd = grub_register_command ("lsapm", grub_cmd_lsapm, 0,
|
||||
N_("Show APM information."));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(lsapm)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
||||
|
||||
|
|
@ -99,7 +99,8 @@ struct legacy_command legacy_commands[] =
|
|||
"Set the default entry to entry number NUM (if not specified, it is"
|
||||
" 0, the first entry) or the entry number saved by savedefault."},
|
||||
/* FIXME: dhcp unsupported. */
|
||||
/* FIXME: displayapm unsupported. */
|
||||
{"displayapm", "lsapm\n", NULL, 0, 0, {}, 0, 0,
|
||||
"Display APM BIOS information."},
|
||||
{"displaymem", "lsmmap\n", NULL, 0, 0, {}, 0, 0,
|
||||
"Display what GRUB thinks the system address space map of the"
|
||||
" machine is, including all regions of physical RAM installed."},
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <grub/memory.h>
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
#include <grub/machine/biosnum.h>
|
||||
#include <grub/machine/apm.h>
|
||||
#endif
|
||||
#include <grub/multiboot.h>
|
||||
#include <grub/cpu/relocator.h>
|
||||
|
@ -194,7 +195,8 @@ grub_multiboot_get_mbi_size (void)
|
|||
+ ALIGN_UP (sizeof(PACKAGE_STRING), 4)
|
||||
+ grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry)
|
||||
+ elf_sec_entsize * elf_sec_num
|
||||
+ 256 * sizeof (struct multiboot_color);
|
||||
+ 256 * sizeof (struct multiboot_color)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_apm_info), 4);
|
||||
}
|
||||
|
||||
/* Fill previously allocated Multiboot mmap. */
|
||||
|
@ -356,6 +358,29 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
|||
ptrorig += ALIGN_UP (sizeof(PACKAGE_STRING), 4);
|
||||
ptrdest += ALIGN_UP (sizeof(PACKAGE_STRING), 4);
|
||||
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
{
|
||||
struct grub_apm_info info;
|
||||
if (grub_apm_get_info (&info))
|
||||
{
|
||||
struct multiboot_apm_info *mbinfo = (void *) ptrorig;
|
||||
|
||||
mbinfo->cseg = info.cseg;
|
||||
mbinfo->offset = info.offset;
|
||||
mbinfo->cseg_16 = info.cseg_16;
|
||||
mbinfo->dseg = info.dseg;
|
||||
mbinfo->flags = info.flags;
|
||||
mbinfo->cseg_len = info.cseg_len;
|
||||
mbinfo->dseg_len = info.dseg_len;
|
||||
mbinfo->cseg_16_len = info.cseg_16_len;
|
||||
mbinfo->version = info.version;
|
||||
|
||||
ptrorig += ALIGN_UP (sizeof (struct multiboot_apm_info), 4);
|
||||
ptrdest += ALIGN_UP (sizeof (struct multiboot_apm_info), 4);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (modcnt)
|
||||
{
|
||||
mbi->flags |= MULTIBOOT_INFO_MODS;
|
||||
|
|
|
@ -21,10 +21,8 @@
|
|||
* FIXME: The following features from the Multiboot specification still
|
||||
* need to be implemented:
|
||||
* - VBE support
|
||||
* - symbol table
|
||||
* - drives table
|
||||
* - ROM configuration table
|
||||
* - APM table
|
||||
*/
|
||||
|
||||
#include <grub/loader.h>
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <grub/memory.h>
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
#include <grub/machine/biosnum.h>
|
||||
#include <grub/machine/apm.h>
|
||||
#endif
|
||||
#include <grub/multiboot.h>
|
||||
#include <grub/cpu/multiboot.h>
|
||||
|
@ -279,7 +280,8 @@ grub_multiboot_get_mbi_size (void)
|
|||
+ elf_sec_entsize * elf_sec_num
|
||||
+ (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_count ()
|
||||
* sizeof (struct multiboot_mmap_entry))
|
||||
+ sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1;
|
||||
+ sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1
|
||||
+ sizeof (struct multiboot_tag_apm) + MULTIBOOT_TAG_ALIGN - 1;
|
||||
}
|
||||
|
||||
/* Fill previously allocated Multiboot mmap. */
|
||||
|
@ -515,6 +517,31 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
|||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
|
||||
}
|
||||
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
{
|
||||
struct grub_apm_info info;
|
||||
if (grub_apm_get_info (&info))
|
||||
{
|
||||
struct multiboot_tag_apm *tag = (struct multiboot_tag_apm *) ptrorig;
|
||||
|
||||
tag->type = MULTIBOOT_TAG_TYPE_APM;
|
||||
tag->size = sizeof (struct multiboot_tag_apm);
|
||||
|
||||
tag->cseg = info.cseg;
|
||||
tag->offset = info.offset;
|
||||
tag->cseg_16 = info.cseg_16;
|
||||
tag->dseg = info.dseg;
|
||||
tag->flags = info.flags;
|
||||
tag->cseg_len = info.cseg_len;
|
||||
tag->dseg_len = info.dseg_len;
|
||||
tag->cseg_16_len = info.cseg_16_len;
|
||||
tag->version = info.version;
|
||||
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
unsigned i;
|
||||
struct module *cur;
|
||||
|
|
48
include/grub/i386/pc/apm.h
Normal file
48
include/grub/i386/pc/apm.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRUB_APM_MACHINE_HEADER
|
||||
#define GRUB_APM_MACHINE_HEADER 1
|
||||
|
||||
#include <grub/types.h>
|
||||
|
||||
struct grub_apm_info
|
||||
{
|
||||
grub_uint16_t cseg;
|
||||
grub_uint32_t offset;
|
||||
grub_uint16_t cseg_16;
|
||||
grub_uint16_t dseg;
|
||||
grub_uint16_t flags;
|
||||
grub_uint16_t cseg_len;
|
||||
grub_uint16_t cseg_16_len;
|
||||
grub_uint16_t dseg_len;
|
||||
grub_uint16_t version;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GRUB_APM_FLAGS_16BITPROTECTED_SUPPORTED = 1,
|
||||
GRUB_APM_FLAGS_32BITPROTECTED_SUPPORTED = 2,
|
||||
GRUB_APM_FLAGS_CPUIDLE_SLOWS_DOWN = 4,
|
||||
GRUB_APM_FLAGS_DISABLED = 8,
|
||||
GRUB_APM_FLAGS_DISENGAGED = 16,
|
||||
};
|
||||
|
||||
int grub_apm_get_info (struct grub_apm_info *info);
|
||||
|
||||
#endif
|
|
@ -20,6 +20,7 @@
|
|||
#define GRUB_INTERRUPT_MACHINE_HEADER 1
|
||||
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/types.h>
|
||||
|
||||
struct grub_bios_int_registers
|
||||
{
|
||||
|
|
19
include/grub/i386/pc/vesa_modes_table.h
Normal file
19
include/grub/i386/pc/vesa_modes_table.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef GRUB_VESA_MODE_TABLE_HEADER
|
||||
#define GRUB_VESA_MODE_TABLE_HEADER 1
|
||||
|
||||
#include <grub/types.h>
|
||||
|
||||
#define GRUB_VESA_MODE_TABLE_START 0x300
|
||||
#define GRUB_VESA_MODE_TABLE_END 0x373
|
||||
|
||||
struct grub_vesa_mode_table_entry {
|
||||
grub_uint16_t width;
|
||||
grub_uint16_t height;
|
||||
grub_uint8_t depth;
|
||||
};
|
||||
|
||||
extern struct grub_vesa_mode_table_entry
|
||||
grub_vesa_mode_table[GRUB_VESA_MODE_TABLE_END
|
||||
- GRUB_VESA_MODE_TABLE_START + 1];
|
||||
|
||||
#endif
|
|
@ -254,6 +254,20 @@ struct multiboot_mod_list
|
|||
};
|
||||
typedef struct multiboot_mod_list multiboot_module_t;
|
||||
|
||||
/* APM BIOS info. */
|
||||
struct multiboot_apm_info
|
||||
{
|
||||
grub_uint16_t version;
|
||||
grub_uint16_t cseg;
|
||||
grub_uint32_t offset;
|
||||
grub_uint16_t cseg_16;
|
||||
grub_uint16_t dseg;
|
||||
grub_uint16_t flags;
|
||||
grub_uint16_t cseg_len;
|
||||
grub_uint16_t cseg_16_len;
|
||||
grub_uint16_t dseg_len;
|
||||
};
|
||||
|
||||
#endif /* ! ASM_FILE */
|
||||
|
||||
#endif /* ! MULTIBOOT_HEADER */
|
||||
|
|
Loading…
Reference in a new issue