1 /* acpi.c - Display acpi tables. */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2008 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19 #include <grub/types.h>
21 #include <grub/misc.h>
22 #include <grub/normal.h>
23 #include <grub/acpi.h>
24 #include <grub/extcmd.h>
25 #include <grub/i18n.h>
28 #pragma GCC diagnostic ignored "-Wcast-align"
30 GRUB_MOD_LICENSE ("GPLv3+");
33 print_strn (grub_uint8_t
*str
, grub_size_t len
)
35 for (; *str
&& len
; str
++, len
--)
36 grub_printf ("%c", *str
);
37 for (len
++; len
; len
--)
41 #define print_field(x) print_strn(x, sizeof (x))
44 disp_acpi_table (struct grub_acpi_table_header
*t
)
46 print_field (t
->signature
);
47 grub_printf ("%4" PRIuGRUB_UINT32_T
"B rev=%u OEM=", t
->length
, t
->revision
);
48 print_field (t
->oemid
);
49 print_field (t
->oemtable
);
50 grub_printf ("OEMrev=%08" PRIxGRUB_UINT32_T
" ", t
->oemrev
);
51 print_field (t
->creator_id
);
52 grub_printf (" %08" PRIxGRUB_UINT32_T
"\n", t
->creator_rev
);
56 disp_madt_table (struct grub_acpi_madt
*t
)
58 struct grub_acpi_madt_entry_header
*d
;
61 disp_acpi_table (&t
->hdr
);
62 grub_printf ("Local APIC=%08" PRIxGRUB_UINT32_T
" Flags=%08"
63 PRIxGRUB_UINT32_T
"\n",
64 t
->lapic_addr
, t
->flags
);
65 len
= t
->hdr
.length
- sizeof (struct grub_acpi_madt
);
67 for (;len
> 0; len
-= d
->len
, d
= (void *) ((grub_uint8_t
*) d
+ d
->len
))
69 grub_printf (" type=%x l=%u ", d
->type
, d
->len
);
73 case GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE
:
75 struct grub_acpi_madt_entry_interrupt_override
*dt
= (void *) d
;
76 grub_printf ("Int Override bus=%x src=%x GSI=%08x Flags=%04x\n",
77 dt
->bus
, dt
->source
, dt
->global_sys_interrupt
,
81 case GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC
:
83 struct grub_acpi_madt_entry_sapic
*dt
= (void *) d
;
84 grub_printf ("IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T
86 dt
->id
, dt
->global_sys_interrupt_base
,
90 case GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC
:
92 struct grub_acpi_madt_entry_lsapic
*dt
= (void *) d
;
93 grub_printf ("LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x",
94 dt
->cpu_id
, dt
->id
, dt
->eid
, dt
->flags
);
95 if (dt
->flags
& GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED
)
96 grub_printf (" Enabled\n");
98 grub_printf (" Disabled\n");
99 if (d
->len
> sizeof (struct grub_acpi_madt_entry_sapic
))
100 grub_printf (" UID val=%08x, Str=%s\n", dt
->cpu_uid
,
104 case GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE
:
106 struct grub_acpi_madt_entry_platform_int_source
*dt
= (void *) d
;
107 static const char * const platint_type
[] =
108 {"Nul", "PMI", "INIT", "CPEI"};
110 grub_printf ("Platform INT flags=%04x type=%02x (%s)"
111 " ID=%02x EID=%02x\n",
112 dt
->flags
, dt
->inttype
,
113 (dt
->inttype
< ARRAY_SIZE (platint_type
))
114 ? platint_type
[dt
->inttype
] : "??", dt
->cpu_id
,
116 grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n",
117 dt
->sapic_vector
, dt
->global_sys_int
, dt
->src_flags
);
121 grub_printf (" ??\n");
127 disp_acpi_xsdt_table (struct grub_acpi_table_header
*t
)
133 len
= t
->length
- sizeof (*t
);
134 desc
= (grub_uint64_t
*) (t
+ 1);
135 for (; len
>= sizeof (*desc
); desc
++, len
-= sizeof (*desc
))
137 #if GRUB_CPU_SIZEOF_VOID_P == 4
138 if (*desc
>= (1ULL << 32))
140 grub_printf ("Unreachable table\n");
144 t
= (struct grub_acpi_table_header
*) (grub_addr_t
) *desc
;
149 if (grub_memcmp (t
->signature
, GRUB_ACPI_MADT_SIGNATURE
,
150 sizeof (t
->signature
)) == 0)
151 disp_madt_table ((struct grub_acpi_madt
*) t
);
158 disp_acpi_rsdt_table (struct grub_acpi_table_header
*t
)
164 len
= t
->length
- sizeof (*t
);
165 desc
= (grub_uint32_t
*) (t
+ 1);
166 for (; len
>= sizeof (*desc
); desc
++, len
-= sizeof (*desc
))
168 t
= (struct grub_acpi_table_header
*) (grub_addr_t
) *desc
;
173 if (grub_memcmp (t
->signature
, GRUB_ACPI_MADT_SIGNATURE
,
174 sizeof (t
->signature
)) == 0)
175 disp_madt_table ((struct grub_acpi_madt
*) t
);
182 disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10
*rsdp
)
184 print_field (rsdp
->signature
);
185 grub_printf ("chksum:%02x, OEM-ID: ", rsdp
->checksum
);
186 print_field (rsdp
->oemid
);
187 grub_printf ("rev=%d\n", rsdp
->revision
);
188 grub_printf ("RSDT=%08" PRIxGRUB_UINT32_T
"\n", rsdp
->rsdt_addr
);
192 disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20
*rsdp
)
194 disp_acpi_rsdpv1 (&rsdp
->rsdpv1
);
195 grub_printf ("len=%d XSDT=%016" PRIxGRUB_UINT64_T
"\n", rsdp
->length
,
199 static const struct grub_arg_option options
[] = {
200 {"v1", '1', 0, N_("Show version 1 tables only."), 0, ARG_TYPE_NONE
},
201 {"v2", '2', 0, N_("Show version 2 and version 3 tables only."), 0, ARG_TYPE_NONE
},
206 grub_cmd_lsacpi (struct grub_extcmd_context
*ctxt
,
207 int argc
__attribute__ ((unused
)),
208 char **args
__attribute__ ((unused
)))
210 if (!ctxt
->state
[1].set
)
212 struct grub_acpi_rsdp_v10
*rsdp1
= grub_acpi_get_rsdpv1 ();
214 grub_printf ("No RSDPv1\n");
217 grub_printf ("RSDPv1 signature:");
218 disp_acpi_rsdpv1 (rsdp1
);
219 disp_acpi_rsdt_table ((void *) (grub_addr_t
) rsdp1
->rsdt_addr
);
223 if (!ctxt
->state
[0].set
)
225 struct grub_acpi_rsdp_v20
*rsdp2
= grub_acpi_get_rsdpv2 ();
227 grub_printf ("No RSDPv2\n");
230 #if GRUB_CPU_SIZEOF_VOID_P == 4
231 if (rsdp2
->xsdt_addr
>= (1ULL << 32))
232 grub_printf ("Unreachable RSDPv2\n");
236 grub_printf ("RSDPv2 signature:");
237 disp_acpi_rsdpv2 (rsdp2
);
238 disp_acpi_xsdt_table ((void *) (grub_addr_t
) rsdp2
->xsdt_addr
);
243 return GRUB_ERR_NONE
;
246 static grub_extcmd_t cmd
;
250 cmd
= grub_register_extcmd ("lsacpi", grub_cmd_lsacpi
, 0, "[-1|-2]",
251 N_("Show ACPI information."), options
);
254 GRUB_MOD_FINI(lsacpi
)
256 grub_unregister_extcmd (cmd
);