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 GRUB_MOD_LICENSE ("GPLv3+");
31 print_strn (grub_uint8_t
*str
, grub_size_t len
)
33 for (; *str
&& len
; str
++, len
--)
34 grub_printf ("%c", *str
);
35 for (len
++; len
; len
--)
39 #define print_field(x) print_strn(x, sizeof (x))
42 disp_acpi_table (struct grub_acpi_table_header
*t
)
44 print_field (t
->signature
);
45 grub_printf ("%4" PRIuGRUB_UINT32_T
"B rev=%u OEM=", t
->length
, t
->revision
);
46 print_field (t
->oemid
);
47 print_field (t
->oemtable
);
48 grub_printf ("OEMrev=%08" PRIxGRUB_UINT32_T
" ", t
->oemrev
);
49 print_field (t
->creator_id
);
50 grub_printf (" %08" PRIxGRUB_UINT32_T
"\n", t
->creator_rev
);
54 disp_madt_table (struct grub_acpi_madt
*t
)
56 struct grub_acpi_madt_entry_header
*d
;
59 disp_acpi_table (&t
->hdr
);
60 grub_printf ("Local APIC=%08" PRIxGRUB_UINT32_T
" Flags=%08"
61 PRIxGRUB_UINT32_T
"\n",
62 t
->lapic_addr
, t
->flags
);
63 len
= t
->hdr
.length
- sizeof (struct grub_acpi_madt
);
65 for (;len
> 0; len
-= d
->len
, d
= (void *) ((grub_uint8_t
*) d
+ d
->len
))
67 grub_printf (" type=%x l=%u ", d
->type
, d
->len
);
71 case GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE
:
73 struct grub_acpi_madt_entry_interrupt_override
*dt
= (void *) d
;
74 grub_printf ("Int Override bus=%x src=%x GSI=%08x Flags=%04x\n",
75 dt
->bus
, dt
->source
, dt
->global_sys_interrupt
,
79 case GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC
:
81 struct grub_acpi_madt_entry_sapic
*dt
= (void *) d
;
82 grub_printf ("IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T
84 dt
->id
, dt
->global_sys_interrupt_base
,
88 case GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC
:
90 struct grub_acpi_madt_entry_lsapic
*dt
= (void *) d
;
91 grub_printf ("LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x",
92 dt
->cpu_id
, dt
->id
, dt
->eid
, dt
->flags
);
93 if (dt
->flags
& GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED
)
94 grub_printf (" Enabled\n");
96 grub_printf (" Disabled\n");
97 if (d
->len
> sizeof (struct grub_acpi_madt_entry_sapic
))
98 grub_printf (" UID val=%08x, Str=%s\n", dt
->cpu_uid
,
102 case GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE
:
104 struct grub_acpi_madt_entry_platform_int_source
*dt
= (void *) d
;
105 static const char * const platint_type
[] =
106 {"Nul", "PMI", "INIT", "CPEI"};
108 grub_printf ("Platform INT flags=%04x type=%02x (%s)"
109 " ID=%02x EID=%02x\n",
110 dt
->flags
, dt
->inttype
,
111 (dt
->inttype
< ARRAY_SIZE (platint_type
))
112 ? platint_type
[dt
->inttype
] : "??", dt
->cpu_id
,
114 grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n",
115 dt
->sapic_vector
, dt
->global_sys_int
, dt
->src_flags
);
119 grub_printf (" ??\n");
125 disp_acpi_xsdt_table (struct grub_acpi_table_header
*t
)
131 len
= t
->length
- sizeof (*t
);
132 desc
= (grub_uint64_t
*) (t
+ 1);
133 for (; len
> 0; desc
++, len
-= sizeof (*desc
))
135 if (sizeof (grub_addr_t
) == 4 && *desc
>= (1ULL << 32))
137 grub_printf ("Unreachable table\n");
140 t
= (struct grub_acpi_table_header
*) (grub_addr_t
) *desc
;
145 if (grub_memcmp (t
->signature
, GRUB_ACPI_MADT_SIGNATURE
,
146 sizeof (t
->signature
)) == 0)
147 disp_madt_table ((struct grub_acpi_madt
*) t
);
154 disp_acpi_rsdt_table (struct grub_acpi_table_header
*t
)
160 len
= t
->length
- sizeof (*t
);
161 desc
= (grub_uint32_t
*) (t
+ 1);
162 for (; len
> 0; desc
++, len
-= sizeof (*desc
))
164 t
= (struct grub_acpi_table_header
*) (grub_addr_t
) *desc
;
169 if (grub_memcmp (t
->signature
, GRUB_ACPI_MADT_SIGNATURE
,
170 sizeof (t
->signature
)) == 0)
171 disp_madt_table ((struct grub_acpi_madt
*) t
);
178 disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10
*rsdp
)
180 print_field (rsdp
->signature
);
181 grub_printf ("chksum:%02x, OEM-ID: ", rsdp
->checksum
);
182 print_field (rsdp
->oemid
);
183 grub_printf ("rev=%d\n", rsdp
->revision
);
184 grub_printf ("RSDT=%08" PRIxGRUB_UINT32_T
"\n", rsdp
->rsdt_addr
);
188 disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20
*rsdp
)
190 disp_acpi_rsdpv1 (&rsdp
->rsdpv1
);
191 grub_printf ("len=%d XSDT=%016" PRIxGRUB_UINT64_T
"\n", rsdp
->length
,
195 static const struct grub_arg_option options
[] = {
196 {"v1", '1', 0, N_("Show v1 tables only."), 0, ARG_TYPE_NONE
},
197 {"v2", '2', 0, N_("Show v2 and v3 tablesv only."), 0, ARG_TYPE_NONE
}
201 grub_cmd_lsacpi (struct grub_extcmd_context
*ctxt
,
202 int argc
__attribute__ ((unused
)),
203 char **args
__attribute__ ((unused
)))
205 if (!ctxt
->state
[1].set
)
207 struct grub_acpi_rsdp_v10
*rsdp1
= grub_acpi_get_rsdpv1 ();
209 grub_printf ("No RSDPv1\n");
212 grub_printf ("RSDPv1 signature:");
213 disp_acpi_rsdpv1 (rsdp1
);
214 disp_acpi_rsdt_table ((void *) (grub_addr_t
) rsdp1
->rsdt_addr
);
218 if (!ctxt
->state
[0].set
)
220 struct grub_acpi_rsdp_v20
*rsdp2
= grub_acpi_get_rsdpv2 ();
222 grub_printf ("No RSDPv2\n");
225 if (sizeof (grub_addr_t
) == 4 && rsdp2
->xsdt_addr
>= (1ULL << 32))
226 grub_printf ("Unreachable RSDPv2\n");
229 grub_printf ("RSDPv2 signature:");
230 disp_acpi_rsdpv2 (rsdp2
);
231 disp_acpi_xsdt_table ((void *) (grub_addr_t
) rsdp2
->xsdt_addr
);
236 return GRUB_ERR_NONE
;
239 static grub_extcmd_t cmd
;
243 cmd
= grub_register_extcmd ("lsacpi", grub_cmd_lsacpi
, 0, N_("[-1|-2]"),
244 N_("Show ACPI information."), options
);
247 GRUB_MOD_FINI(lsacpi
)
249 grub_unregister_extcmd (cmd
);