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>
29 print_strn (grub_uint8_t
*str
, grub_size_t len
)
31 for (; *str
&& len
; str
++, len
--)
32 grub_printf ("%c", *str
);
33 for (len
++; len
; len
--)
37 #define print_field(x) print_strn(x, sizeof (x))
40 disp_acpi_table (struct grub_acpi_table_header
*t
)
42 print_field (t
->signature
);
43 grub_printf ("%4" PRIuGRUB_UINT32_T
"B rev=%u OEM=", t
->length
, t
->revision
);
44 print_field (t
->oemid
);
45 print_field (t
->oemtable
);
46 grub_printf ("OEMrev=%08" PRIxGRUB_UINT32_T
" ", t
->oemrev
);
47 print_field (t
->creator_id
);
48 grub_printf (" %08" PRIxGRUB_UINT32_T
"\n", t
->creator_rev
);
52 disp_madt_table (struct grub_acpi_madt
*t
)
54 struct grub_acpi_madt_entry_header
*d
;
57 disp_acpi_table (&t
->hdr
);
58 grub_printf ("Local APIC=%08" PRIxGRUB_UINT32_T
" Flags=%08"
59 PRIxGRUB_UINT32_T
"\n",
60 t
->lapic_addr
, t
->flags
);
61 len
= t
->hdr
.length
- sizeof (struct grub_acpi_madt
);
63 for (;len
> 0; len
-= d
->len
, d
= (void *) ((grub_uint8_t
*) d
+ d
->len
))
65 grub_printf (" type=%x l=%u ", d
->type
, d
->len
);
69 case GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE
:
71 struct grub_acpi_madt_entry_interrupt_override
*dt
= (void *) d
;
72 grub_printf ("Int Override bus=%x src=%x GSI=%08x Flags=%04x\n",
73 dt
->bus
, dt
->source
, dt
->global_sys_interrupt
,
77 case GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC
:
79 struct grub_acpi_madt_entry_sapic
*dt
= (void *) d
;
80 grub_printf ("IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T
82 dt
->id
, dt
->global_sys_interrupt_base
,
86 case GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC
:
88 struct grub_acpi_madt_entry_lsapic
*dt
= (void *) d
;
89 grub_printf ("LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x",
90 dt
->cpu_id
, dt
->id
, dt
->eid
, dt
->flags
);
91 if (dt
->flags
& GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED
)
92 grub_printf (" Enabled\n");
94 grub_printf (" Disabled\n");
95 if (d
->len
> sizeof (struct grub_acpi_madt_entry_sapic
))
96 grub_printf (" UID val=%08x, Str=%s\n", dt
->cpu_uid
,
100 case GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE
:
102 struct grub_acpi_madt_entry_platform_int_source
*dt
= (void *) d
;
103 static const char * const platint_type
[] =
104 {"Nul", "PMI", "INIT", "CPEI"};
106 grub_printf ("Platform INT flags=%04x type=%02x (%s)"
107 " ID=%02x EID=%02x\n",
108 dt
->flags
, dt
->inttype
,
109 (dt
->inttype
< ARRAY_SIZE (platint_type
))
110 ? platint_type
[dt
->inttype
] : "??", dt
->cpu_id
,
112 grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n",
113 dt
->sapic_vector
, dt
->global_sys_int
, dt
->src_flags
);
117 grub_printf (" ??\n");
123 disp_acpi_xsdt_table (struct grub_acpi_table_header
*t
)
129 len
= t
->length
- sizeof (*t
);
130 desc
= (grub_uint64_t
*) (t
+ 1);
131 for (; len
> 0; desc
++, len
-= sizeof (*desc
))
133 if (sizeof (grub_addr_t
) == 4 && *desc
>= (1ULL << 32))
135 grub_printf ("Unreachable table\n");
138 t
= (struct grub_acpi_table_header
*) (grub_addr_t
) *desc
;
143 if (grub_memcmp (t
->signature
, GRUB_ACPI_MADT_SIGNATURE
,
144 sizeof (t
->signature
)) == 0)
145 disp_madt_table ((struct grub_acpi_madt
*) t
);
152 disp_acpi_rsdt_table (struct grub_acpi_table_header
*t
)
158 len
= t
->length
- sizeof (*t
);
159 desc
= (grub_uint32_t
*) (t
+ 1);
160 for (; len
> 0; desc
++, len
-= sizeof (*desc
))
162 t
= (struct grub_acpi_table_header
*) (grub_addr_t
) *desc
;
167 if (grub_memcmp (t
->signature
, GRUB_ACPI_MADT_SIGNATURE
,
168 sizeof (t
->signature
)) == 0)
169 disp_madt_table ((struct grub_acpi_madt
*) t
);
176 disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10
*rsdp
)
178 print_field (rsdp
->signature
);
179 grub_printf ("chksum:%02x, OEM-ID: ", rsdp
->checksum
);
180 print_field (rsdp
->oemid
);
181 grub_printf ("rev=%d\n", rsdp
->revision
);
182 grub_printf ("RSDT=%08" PRIxGRUB_UINT32_T
"\n", rsdp
->rsdt_addr
);
186 disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20
*rsdp
)
188 disp_acpi_rsdpv1 (&rsdp
->rsdpv1
);
189 grub_printf ("len=%d XSDT=%016" PRIxGRUB_UINT64_T
"\n", rsdp
->length
,
193 static const struct grub_arg_option options
[] = {
194 {"v1", '1', 0, N_("Show v1 tables only."), 0, ARG_TYPE_NONE
},
195 {"v2", '2', 0, N_("Show v2 and v3 tablesv only."), 0, ARG_TYPE_NONE
}
199 grub_cmd_lsacpi (struct grub_extcmd_context
*ctxt
,
200 int argc
__attribute__ ((unused
)),
201 char **args
__attribute__ ((unused
)))
203 if (!ctxt
->state
[1].set
)
205 struct grub_acpi_rsdp_v10
*rsdp1
= grub_acpi_get_rsdpv1 ();
207 grub_printf ("No RSDPv1\n");
210 grub_printf ("RSDPv1 signature:");
211 disp_acpi_rsdpv1 (rsdp1
);
212 disp_acpi_rsdt_table ((void *) (grub_addr_t
) rsdp1
->rsdt_addr
);
216 if (!ctxt
->state
[0].set
)
218 struct grub_acpi_rsdp_v20
*rsdp2
= grub_acpi_get_rsdpv2 ();
220 grub_printf ("No RSDPv2\n");
223 if (sizeof (grub_addr_t
) == 4 && rsdp2
->xsdt_addr
>= (1ULL << 32))
224 grub_printf ("Unreachable RSDPv2\n");
227 grub_printf ("RSDPv2 signature:");
228 disp_acpi_rsdpv2 (rsdp2
);
229 disp_acpi_xsdt_table ((void *) (grub_addr_t
) rsdp2
->xsdt_addr
);
234 return GRUB_ERR_NONE
;
237 static grub_extcmd_t cmd
;
241 cmd
= grub_register_extcmd ("lsacpi", grub_cmd_lsacpi
, GRUB_COMMAND_FLAG_BOTH
,
243 N_("Show ACPI information."), options
);
246 GRUB_MOD_FINI(lsacpi
)
248 grub_unregister_extcmd (cmd
);