]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* commands/lsacpi.c: New file.
authorTristan Gingold <gingold@free.fr>
Tue, 31 Aug 2010 23:05:32 +0000 (01:05 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 31 Aug 2010 23:05:32 +0000 (01:05 +0200)
* grub-core/Makefile.core.def (lsacpi): New module.
* include/grub/acpi.h (GRUB_ACPI_FADT_SIGNATURE): New definition.
(GRUB_ACPI_MADT_SIGNATURE): Likewise.
(grub_acpi_madt_entry_header): New struct.
(grub_acpi_madt): Likewise.
(grub_acpi_madt_entry_interrupt_override): Likewise.
(grub_acpi_madt_entry_sapic): Likewise.
(grub_acpi_madt_entry_lsapic): Likewise.
(grub_acpi_madt_entry_platform_int_source): Likewise.
* include/grub/types.h (PRIxGRUB_UINT32_T): New definition.
(PRIuGRUB_UINT32_T): Likewise.
(PRIxGRUB_UINT64_T): Likewise.

Also-By: Robert Millan <rmh.grub@aybabtu.com>
Also-By: Vladimir Serbinenko <phcoder@gmail.com>
ChangeLog.gingold1 [new file with mode: 0644]
grub-core/Makefile.core.def
grub-core/commands/acpi.c
grub-core/commands/lsacpi.c [new file with mode: 0644]
include/grub/acpi.h
include/grub/types.h

diff --git a/ChangeLog.gingold1 b/ChangeLog.gingold1
new file mode 100644 (file)
index 0000000..b2bef5d
--- /dev/null
@@ -0,0 +1,17 @@
+2008-01-28  Tristan Gingold  <gingold@free.fr>
+2010-01-18  Robert Millan  <rmh.grub@aybabtu.com>
+2010-08-31  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       * commands/lsacpi.c: New file.
+       * grub-core/Makefile.core.def (lsacpi): New module.
+       * include/grub/acpi.h (GRUB_ACPI_FADT_SIGNATURE): New definition.
+       (GRUB_ACPI_MADT_SIGNATURE): Likewise.
+       (grub_acpi_madt_entry_header): New struct.
+       (grub_acpi_madt): Likewise.
+       (grub_acpi_madt_entry_interrupt_override): Likewise.
+       (grub_acpi_madt_entry_sapic): Likewise.
+       (grub_acpi_madt_entry_lsapic): Likewise.
+       (grub_acpi_madt_entry_platform_int_source): Likewise.
+       * include/grub/types.h (PRIxGRUB_UINT32_T): New definition.
+       (PRIuGRUB_UINT32_T): Likewise.
+       (PRIxGRUB_UINT64_T): Likewise.
index 353b9d123b65695401793e9fc43d7dc7bdb086af..6f116770e41faaf8201bb92c5a737c2d752dfa13 100644 (file)
@@ -402,7 +402,7 @@ module = {
 module = {
   name = acpi;
 
-  x86 = commands/acpi.c;
+  common = commands/acpi.c;
   x86_efi = commands/efi/acpi.c;
   i386_pc = commands/i386/pc/acpi.c;
   i386_coreboot = commands/i386/pc/acpi.c;
@@ -414,6 +414,17 @@ module = {
   enable = i386_multiboot;
 };
 
+module = {
+  name = lsacpi;
+
+  common = commands/lsacpi.c;
+
+  enable = x86_efi;
+  enable = i386_pc;
+  enable = i386_coreboot;
+  enable = i386_multiboot;
+};
+
 module = {
   name = blocklist;
   common = commands/blocklist.c;
index 884ddf0007fbc277c5d2c69719316260e20c285c..016e6fd9c8bf02add15a1a37c4f5241e6084c1af 100644 (file)
@@ -325,7 +325,7 @@ setup_common_tables (void)
 
       /* If it's FADT correct DSDT and FACS addresses. */
       fadt = (struct grub_acpi_fadt *) cur->addr;
-      if (grub_memcmp (fadt->hdr.signature, "FACP",
+      if (grub_memcmp (fadt->hdr.signature, GRUB_ACPI_FADT_SIGNATURE,
                       sizeof (fadt->hdr.signature)) == 0)
        {
          fadt->dsdt_addr = PTR_TO_UINT32 (table_dsdt);
@@ -529,7 +529,7 @@ grub_cmd_acpi (struct grub_extcmd *cmd,
              struct grub_acpi_fadt *fadt = (struct grub_acpi_fadt *) curtable;
 
              /* Set root header variables to the same values
-                as FACP by default. */
+                as FADT by default. */
              grub_memcpy (&root_oemid, &(fadt->hdr.oemid),
                           sizeof (root_oemid));
              grub_memcpy (&root_oemtable, &(fadt->hdr.oemtable),
diff --git a/grub-core/commands/lsacpi.c b/grub-core/commands/lsacpi.c
new file mode 100644 (file)
index 0000000..d20b80f
--- /dev/null
@@ -0,0 +1,250 @@
+/* acpi.c  - Display acpi tables.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  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/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+#include <grub/acpi.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+#include <grub/dl.h>
+
+static void
+print_strn (grub_uint8_t *str, grub_size_t len)
+{
+  for (; *str && len; str++, len--)
+    grub_printf ("%c", *str);
+  for (len++; len; len--)
+    grub_printf (" ");  
+}
+
+#define print_field(x) print_strn(x, sizeof (x))
+
+static void
+disp_acpi_table (struct grub_acpi_table_header *t)
+{
+  print_field (t->signature);
+  grub_printf ("%4" PRIuGRUB_UINT32_T "B rev=%u OEM=", t->length, t->revision);
+  print_field (t->oemid);
+  print_field (t->oemtable);
+  grub_printf ("OEMrev=%08" PRIxGRUB_UINT32_T " ", t->oemrev);
+  print_field (t->creator_id);
+  grub_printf (" %08" PRIxGRUB_UINT32_T "\n", t->creator_rev);
+}
+
+static void
+disp_madt_table (struct grub_acpi_madt *t)
+{
+  struct grub_acpi_madt_entry_header *d;
+  grub_uint32_t len;
+
+  disp_acpi_table (&t->hdr);
+  grub_printf ("Local APIC=%08" PRIxGRUB_UINT32_T "  Flags=%08"
+              PRIxGRUB_UINT32_T "\n",
+              t->lapic_addr, t->flags);
+  len = t->hdr.length - sizeof (struct grub_acpi_madt);
+  d = t->entries;
+  for (;len > 0; len -= d->len, d = (void *) ((grub_uint8_t *) d + d->len))
+    {
+      grub_printf ("  type=%x l=%u ", d->type, d->len);
+
+      switch (d->type)
+       {
+       case GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE:
+         {
+           struct grub_acpi_madt_entry_interrupt_override *dt = (void *) d;
+           grub_printf ("Int Override bus=%x src=%x GSI=%08x Flags=%04x\n",
+                        dt->bus, dt->source, dt->global_sys_interrupt,
+                        dt->flags);
+         }
+         break;
+       case GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC:
+         {
+           struct grub_acpi_madt_entry_sapic *dt = (void *) d;
+           grub_printf ("IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T
+                        "\n",
+                        dt->id, dt->global_sys_interrupt_base,
+                        dt->addr);
+         }
+         break;
+       case GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC:
+         {
+           struct grub_acpi_madt_entry_lsapic *dt = (void *) d;
+           grub_printf ("LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x",
+                        dt->cpu_id, dt->id, dt->eid, dt->flags);
+           if (dt->flags & GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED)
+             grub_printf (" Enabled\n");
+           else
+             grub_printf (" Disabled\n");
+           if (d->len > sizeof (struct grub_acpi_madt_entry_sapic))
+             grub_printf ("    UID val=%08x, Str=%s\n", dt->cpu_uid,
+                          dt->cpu_uid_str);
+         }
+         break;
+       case GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE:
+         {
+           struct grub_acpi_madt_entry_platform_int_source *dt = (void *) d;
+           static const char * const platint_type[] =
+             {"Nul", "PMI", "INIT", "CPEI"};
+
+           grub_printf ("Platform INT flags=%04x type=%02x (%s)"
+                        " ID=%02x EID=%02x\n",
+                        dt->flags, dt->inttype,
+                        (dt->inttype < ARRAY_SIZE (platint_type))
+                        ? platint_type[dt->inttype] : "??", dt->cpu_id,
+                        dt->cpu_eid);
+           grub_printf ("      IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n",
+                        dt->sapic_vector, dt->global_sys_int, dt->src_flags);
+         }
+         break;
+       default:
+         grub_printf (" ??\n");
+       }
+    }
+}
+
+static void
+disp_acpi_xsdt_table (struct grub_acpi_table_header *t)
+{
+  grub_uint32_t len;
+  grub_uint64_t *desc;
+
+  disp_acpi_table (t);
+  len = t->length - sizeof (*t);
+  desc = (grub_uint64_t *) (t + 1);
+  for (; len > 0; desc++, len -= sizeof (*desc))
+    {
+      if (sizeof (grub_addr_t) == 4 && *desc >= (1ULL << 32))
+       {
+         grub_printf ("Unreachable table\n");
+         continue;
+       }
+      t = (struct grub_acpi_table_header *) (grub_addr_t) *desc;
+
+      if (t == NULL)
+       continue;
+
+      if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE,
+                      sizeof (t->signature)) == 0)
+       disp_madt_table ((struct grub_acpi_madt *) t);
+      else
+       disp_acpi_table (t);
+    }
+}
+
+static void
+disp_acpi_rsdt_table (struct grub_acpi_table_header *t)
+{
+  grub_uint32_t len;
+  grub_uint32_t *desc;
+
+  disp_acpi_table (t);
+  len = t->length - sizeof (*t);
+  desc = (grub_uint32_t *) (t + 1);
+  for (; len > 0; desc++, len -= sizeof (*desc))
+    {
+      t = (struct grub_acpi_table_header *) (grub_addr_t) *desc;
+
+      if (t == NULL)
+       continue;
+
+      if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE,
+                      sizeof (t->signature)) == 0)
+       disp_madt_table ((struct grub_acpi_madt *) t);
+      else
+       disp_acpi_table (t);
+    }
+}
+
+static void
+disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10 *rsdp)
+{
+  print_field (rsdp->signature);
+  grub_printf ("chksum:%02x, OEM-ID: ", rsdp->checksum);
+  print_field (rsdp->oemid);
+  grub_printf ("rev=%d\n", rsdp->revision);
+  grub_printf ("RSDT=%08" PRIxGRUB_UINT32_T "\n", rsdp->rsdt_addr);
+}
+
+static void
+disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp)
+{
+  disp_acpi_rsdpv1 (&rsdp->rsdpv1);
+  grub_printf ("len=%d XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length,
+              rsdp->xsdt_addr);
+}
+
+static const struct grub_arg_option options[] = {
+  {"v1", '1', 0, N_("Show v1 tables only."), 0, ARG_TYPE_NONE},
+  {"v2", '2', 0, N_("Show v2 and v3 tablesv only."), 0, ARG_TYPE_NONE}
+};
+
+static grub_err_t
+grub_cmd_lsacpi (struct grub_extcmd *cmd, int argc __attribute__ ((unused)),
+                char **args __attribute__ ((unused)))
+{
+  if (!cmd->state[1].set)
+    {
+      struct grub_acpi_rsdp_v10 *rsdp1 = grub_acpi_get_rsdpv1 ();
+      if (!rsdp1)
+       grub_printf ("No RSDPv1\n");
+      else
+       {
+         grub_printf ("RSDPv1 signature:");
+         disp_acpi_rsdpv1 (rsdp1);
+         disp_acpi_rsdt_table ((void *) (grub_addr_t) rsdp1->rsdt_addr);
+       }
+    }
+
+  if (!cmd->state[0].set)
+    {
+      struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 ();
+      if (!rsdp2)
+       grub_printf ("No RSDPv2\n");
+      else
+       {
+         if (sizeof (grub_addr_t) == 4 && rsdp2->xsdt_addr >= (1ULL << 32))
+             grub_printf ("Unreachable RSDPv2\n");
+         else
+           {
+             grub_printf ("RSDPv2 signature:");
+             disp_acpi_rsdpv2 (rsdp2);
+             disp_acpi_xsdt_table ((void *) (grub_addr_t) rsdp2->xsdt_addr);
+             grub_printf ("\n");
+           }
+       }
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(lsapi)
+{
+  cmd = grub_register_extcmd ("lsacpi", grub_cmd_lsacpi, GRUB_COMMAND_FLAG_BOTH,
+                             N_("[-1|-2]"),
+                             N_("Show ACPI information."), options);
+}
+
+GRUB_MOD_FINI(lsacpi)
+{
+  grub_unregister_extcmd (cmd);
+}
+
+
index 7933db8241646197b09376875fb49ccbace5f5ce..17ffd7686d9d45da82cf47ad128c777556d45f59 100644 (file)
@@ -53,6 +53,8 @@ struct grub_acpi_table_header
   grub_uint32_t creator_rev;
 } __attribute__ ((packed));
 
+#define GRUB_ACPI_FADT_SIGNATURE "FACP"
+
 struct grub_acpi_fadt
 {
   struct grub_acpi_table_header hdr;
@@ -64,6 +66,77 @@ struct grub_acpi_fadt
   grub_uint8_t somefields2[96];
 } __attribute__ ((packed));
 
+#define GRUB_ACPI_MADT_SIGNATURE "APIC"
+
+struct grub_acpi_madt_entry_header
+{
+  grub_uint8_t type;
+  grub_uint8_t len;
+};
+
+struct grub_acpi_madt
+{
+  struct grub_acpi_table_header hdr;
+  grub_uint32_t lapic_addr;
+  grub_uint32_t flags;
+  struct grub_acpi_madt_entry_header entries[0];
+};
+
+enum
+  {
+    GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE = 2,
+    GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC = 6,
+    GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC = 7,
+    GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE = 8
+  };
+
+struct grub_acpi_madt_entry_interrupt_override
+{
+  struct grub_acpi_madt_entry_header hdr;
+  grub_uint8_t bus;
+  grub_uint8_t source;
+  grub_uint32_t global_sys_interrupt;
+  grub_uint16_t flags;
+};
+
+struct grub_acpi_madt_entry_sapic
+{
+  struct grub_acpi_madt_entry_header hdr;
+  grub_uint8_t id;
+  grub_uint8_t pad;
+  grub_uint32_t global_sys_interrupt_base;
+  grub_uint64_t addr;
+};
+
+struct grub_acpi_madt_entry_lsapic
+{
+  struct grub_acpi_madt_entry_header hdr;
+  grub_uint8_t cpu_id;
+  grub_uint8_t id;
+  grub_uint8_t eid;
+  grub_uint8_t pad[3];
+  grub_uint32_t flags;
+  grub_uint32_t cpu_uid;
+  grub_uint8_t cpu_uid_str[0];
+};
+
+struct grub_acpi_madt_entry_platform_int_source
+{
+  struct grub_acpi_madt_entry_header hdr;
+  grub_uint16_t flags;
+  grub_uint8_t inttype;
+  grub_uint8_t cpu_id;
+  grub_uint8_t cpu_eid;
+  grub_uint8_t sapic_vector;
+  grub_uint32_t global_sys_int;
+  grub_uint32_t src_flags;
+};
+
+enum
+  {
+    GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED = 1
+  };
+
 struct grub_acpi_rsdp_v10 *grub_acpi_get_rsdpv1 (void);
 struct grub_acpi_rsdp_v20 *grub_acpi_get_rsdpv2 (void);
 struct grub_acpi_rsdp_v10 *grub_machine_acpi_get_rsdpv1 (void);
index 4499e453820319998d19c3dec2df2a0e4a903bf2..1cabc2ecfe664d16daa0ebd099b9c3dc11ad3ebb 100644 (file)
@@ -69,10 +69,14 @@ typedef long long           grub_int64_t;
 typedef unsigned char          grub_uint8_t;
 typedef unsigned short         grub_uint16_t;
 typedef unsigned               grub_uint32_t;
+# define PRIxGRUB_UINT32_T     "x"
+# define PRIuGRUB_UINT32_T     "u"
 #if GRUB_CPU_SIZEOF_LONG == 8
 typedef unsigned long          grub_uint64_t;
+# define PRIxGRUB_UINT64_T     "lx"
 #else
 typedef unsigned long long     grub_uint64_t;
+# define PRIxGRUB_UINT64_T     "llx"
 #endif
 
 /* Misc types.  */