123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- /* 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>
- #pragma GCC diagnostic ignored "-Wcast-align"
- GRUB_MOD_LICENSE ("GPLv3+");
- 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 chksum=0x%02x (%s) OEM=", t->length, t->revision, t->checksum,
- grub_byte_checksum (t, t->length) == 0 ? "valid" : "invalid");
- 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))
- {
- switch (d->type)
- {
- case GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC:
- {
- struct grub_acpi_madt_entry_lapic *dt = (void *) d;
- grub_printf (" LAPIC ACPI_ID=%02x APIC_ID=%02x Flags=%08x\n",
- dt->acpiid, dt->apicid, dt->flags);
- if (dt->hdr.len != sizeof (*dt))
- grub_printf (" table size mismatch %d != %d\n", dt->hdr.len,
- (int) sizeof (*dt));
- break;
- }
- case GRUB_ACPI_MADT_ENTRY_TYPE_IOAPIC:
- {
- struct grub_acpi_madt_entry_ioapic *dt = (void *) d;
- grub_printf (" IOAPIC ID=%02x address=%08x GSI=%08x\n",
- dt->id, dt->address, dt->global_sys_interrupt);
- if (dt->hdr.len != sizeof (*dt))
- grub_printf (" table size mismatch %d != %d\n", dt->hdr.len,
- (int) sizeof (*dt));
- if (dt->pad)
- grub_printf (" non-zero pad: %02x\n", dt->pad);
- break;
- }
- 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);
- if (dt->hdr.len != sizeof (*dt))
- grub_printf (" table size mismatch %d != %d\n", dt->hdr.len,
- (int) sizeof (*dt));
- }
- break;
- case GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC_NMI:
- {
- struct grub_acpi_madt_entry_lapic_nmi *dt = (void *) d;
- grub_printf (" LAPIC_NMI ACPI_ID=%02x Flags=%04x lint=%02x\n",
- dt->acpiid, dt->flags, dt->lint);
- if (dt->hdr.len != sizeof (*dt))
- grub_printf (" table size mismatch %d != %d\n", dt->hdr.len,
- (int) sizeof (*dt));
- 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);
- if (dt->hdr.len != sizeof (*dt))
- grub_printf (" table size mismatch %d != %d\n", dt->hdr.len,
- (int) sizeof (*dt));
- if (dt->pad)
- grub_printf (" non-zero pad: %02x\n", dt->pad);
- }
- 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);
- if (dt->hdr.len != sizeof (*dt) + grub_strlen ((char *) dt->cpu_uid_str) + 1)
- grub_printf (" table size mismatch %d != %d\n", dt->hdr.len,
- (int) sizeof (*dt));
- if (dt->pad[0] || dt->pad[1] || dt->pad[2])
- grub_printf (" non-zero pad: %02x%02x%02x\n", dt->pad[0], dt->pad[1], dt->pad[2]);
- }
- 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 (" type=%x l=%u ", d->type, d->len);
- 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 >= sizeof (*desc); desc++, len -= sizeof (*desc))
- {
- #if GRUB_CPU_SIZEOF_VOID_P == 4
- if (*desc >= (1ULL << 32))
- {
- grub_printf ("Unreachable table\n");
- continue;
- }
- #endif
- 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 >= sizeof (*desc); 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 (%s), OEM-ID: ", rsdp->checksum, grub_byte_checksum (rsdp, sizeof (*rsdp)) == 0 ? "valid" : "invalid");
- 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 chksum=%02x (%s) XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length, rsdp->checksum, grub_byte_checksum (rsdp, rsdp->length) == 0 ? "valid" : "invalid",
- rsdp->xsdt_addr);
- if (rsdp->length != sizeof (*rsdp))
- grub_printf (" length mismatch %d != %d\n", rsdp->length,
- (int) sizeof (*rsdp));
- if (rsdp->reserved[0] || rsdp->reserved[1] || rsdp->reserved[2])
- grub_printf (" non-zero reserved %02x%02x%02x\n", rsdp->reserved[0], rsdp->reserved[1], rsdp->reserved[2]);
- }
- static const struct grub_arg_option options[] = {
- {"v1", '1', 0, N_("Show version 1 tables only."), 0, ARG_TYPE_NONE},
- {"v2", '2', 0, N_("Show version 2 and version 3 tables only."), 0, ARG_TYPE_NONE},
- {0, 0, 0, 0, 0, 0}
- };
- static grub_err_t
- grub_cmd_lsacpi (struct grub_extcmd_context *ctxt,
- int argc __attribute__ ((unused)),
- char **args __attribute__ ((unused)))
- {
- if (!ctxt->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 (!ctxt->state[0].set)
- {
- struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 ();
- if (!rsdp2)
- grub_printf ("No RSDPv2\n");
- else
- {
- #if GRUB_CPU_SIZEOF_VOID_P == 4
- if (rsdp2->xsdt_addr >= (1ULL << 32))
- grub_printf ("Unreachable RSDPv2\n");
- else
- #endif
- {
- 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, 0, "[-1|-2]",
- N_("Show ACPI information."), options);
- }
- GRUB_MOD_FINI(lsacpi)
- {
- grub_unregister_extcmd (cmd);
- }
|