]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Implement APM
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Wed, 15 Sep 2010 09:42:18 +0000 (11:42 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Wed, 15 Sep 2010 09:42:18 +0000 (11:42 +0200)
grub-core/Makefile.core.def
grub-core/commands/i386/pc/lsapm.c [new file with mode: 0644]
grub-core/lib/legacy_parse.c
grub-core/loader/i386/multiboot_mbi.c
grub-core/loader/multiboot.c
grub-core/loader/multiboot_mbi2.c
include/grub/i386/pc/apm.h [new file with mode: 0644]
include/grub/i386/pc/int.h
include/grub/i386/pc/vesa_modes_table.h [new file with mode: 0644]
include/multiboot.h

index 03505ad5aaf46585eaa5b5c13b3dba469d5bae60..584b9754d0b16c6c76182b7fabf68fec3cb09c12 100644 (file)
@@ -1433,3 +1433,9 @@ module = {
   name = testload;
   common = commands/testload.c;
 };
+
+module = {
+  name = lsapm;
+  common = commands/i386/pc/lsapm.c;
+  enable = i386_pc;
+};
diff --git a/grub-core/commands/i386/pc/lsapm.c b/grub-core/commands/i386/pc/lsapm.c
new file mode 100644 (file)
index 0000000..30475d2
--- /dev/null
@@ -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, &regs);
+  
+  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, &regs);
+
+  /* connect APM */
+  regs.eax = 0x5303;
+  regs.ebx = 0;
+  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
+  grub_bios_interrupt (0x15, &regs);
+
+  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);
+}
+
+
index 959d8367df771e0d3bc264b3e5e368b44b6e6516..024d425e89f619602513205a6b9417e0afedce67 100644 (file)
@@ -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."},
index bf17863cfc0dea78a1334f1d50374e0d7ff09572..2cce397467b8beba1093f19ad019e7abd4032bca 100644 (file)
@@ -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;
index 8780ec061f751effe0bf1af24c47e693ddd7acb4..d5cb42604ae336be9f69a41cb80cfe40124fd6c7 100644 (file)
  *  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>
index f453dcc6a422c106f2f54c02ed7011c59b5fb30a..2e680125247e12c13905fd427155152f191a4041 100644 (file)
@@ -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;
diff --git a/include/grub/i386/pc/apm.h b/include/grub/i386/pc/apm.h
new file mode 100644 (file)
index 0000000..6d9e8c6
--- /dev/null
@@ -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
index e1c463925e447ad7c852312147bc821bdcf7c444..de23775d08206d660345450c71dcf1ef1ed1389d 100644 (file)
@@ -20,6 +20,7 @@
 #define GRUB_INTERRUPT_MACHINE_HEADER  1
 
 #include <grub/symbol.h>
+#include <grub/types.h>
 
 struct grub_bios_int_registers
 {
diff --git a/include/grub/i386/pc/vesa_modes_table.h b/include/grub/i386/pc/vesa_modes_table.h
new file mode 100644 (file)
index 0000000..376ca37
--- /dev/null
@@ -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
index fda863e85741e7ed142dbb2dac1c30185eb0f348..ed71e6b96784e2f4bb8ecb34ca7cbec83b4c1192 100644 (file)
@@ -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 */