]> git.proxmox.com Git - grub2.git/blob - grub-core/commands/lsacpi.c
f5ab0db396c0b54501d474bff500161224fd6e16
[grub2.git] / grub-core / commands / lsacpi.c
1 /* acpi.c - Display acpi tables. */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2008 Free Software Foundation, Inc.
5 *
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.
10 *
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.
15 *
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/>.
18 */
19 #include <grub/types.h>
20 #include <grub/mm.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>
26 #include <grub/dl.h>
27
28 #pragma GCC diagnostic ignored "-Wcast-align"
29
30 GRUB_MOD_LICENSE ("GPLv3+");
31
32 static void
33 print_strn (grub_uint8_t *str, grub_size_t len)
34 {
35 for (; *str && len; str++, len--)
36 grub_printf ("%c", *str);
37 for (len++; len; len--)
38 grub_printf (" ");
39 }
40
41 #define print_field(x) print_strn(x, sizeof (x))
42
43 static void
44 disp_acpi_table (struct grub_acpi_table_header *t)
45 {
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);
53 }
54
55 static void
56 disp_madt_table (struct grub_acpi_madt *t)
57 {
58 struct grub_acpi_madt_entry_header *d;
59 grub_uint32_t len;
60
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);
66 d = t->entries;
67 for (;len > 0; len -= d->len, d = (void *) ((grub_uint8_t *) d + d->len))
68 {
69 grub_printf (" type=%x l=%u ", d->type, d->len);
70
71 switch (d->type)
72 {
73 case GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE:
74 {
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,
78 dt->flags);
79 }
80 break;
81 case GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC:
82 {
83 struct grub_acpi_madt_entry_sapic *dt = (void *) d;
84 grub_printf ("IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T
85 "\n",
86 dt->id, dt->global_sys_interrupt_base,
87 dt->addr);
88 }
89 break;
90 case GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC:
91 {
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");
97 else
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,
101 dt->cpu_uid_str);
102 }
103 break;
104 case GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE:
105 {
106 struct grub_acpi_madt_entry_platform_int_source *dt = (void *) d;
107 static const char * const platint_type[] =
108 {"Nul", "PMI", "INIT", "CPEI"};
109
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,
115 dt->cpu_eid);
116 grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n",
117 dt->sapic_vector, dt->global_sys_int, dt->src_flags);
118 }
119 break;
120 default:
121 grub_printf (" ??\n");
122 }
123 }
124 }
125
126 static void
127 disp_acpi_xsdt_table (struct grub_acpi_table_header *t)
128 {
129 grub_uint32_t len;
130 grub_uint64_t *desc;
131
132 disp_acpi_table (t);
133 len = t->length - sizeof (*t);
134 desc = (grub_uint64_t *) (t + 1);
135 for (; len >= sizeof (*desc); desc++, len -= sizeof (*desc))
136 {
137 #if GRUB_CPU_SIZEOF_VOID_P == 4
138 if (*desc >= (1ULL << 32))
139 {
140 grub_printf ("Unreachable table\n");
141 continue;
142 }
143 #endif
144 t = (struct grub_acpi_table_header *) (grub_addr_t) *desc;
145
146 if (t == NULL)
147 continue;
148
149 if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE,
150 sizeof (t->signature)) == 0)
151 disp_madt_table ((struct grub_acpi_madt *) t);
152 else
153 disp_acpi_table (t);
154 }
155 }
156
157 static void
158 disp_acpi_rsdt_table (struct grub_acpi_table_header *t)
159 {
160 grub_uint32_t len;
161 grub_uint32_t *desc;
162
163 disp_acpi_table (t);
164 len = t->length - sizeof (*t);
165 desc = (grub_uint32_t *) (t + 1);
166 for (; len >= sizeof (*desc); desc++, len -= sizeof (*desc))
167 {
168 t = (struct grub_acpi_table_header *) (grub_addr_t) *desc;
169
170 if (t == NULL)
171 continue;
172
173 if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE,
174 sizeof (t->signature)) == 0)
175 disp_madt_table ((struct grub_acpi_madt *) t);
176 else
177 disp_acpi_table (t);
178 }
179 }
180
181 static void
182 disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10 *rsdp)
183 {
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);
189 }
190
191 static void
192 disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp)
193 {
194 disp_acpi_rsdpv1 (&rsdp->rsdpv1);
195 grub_printf ("len=%d XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length,
196 rsdp->xsdt_addr);
197 }
198
199 static const struct grub_arg_option options[] = {
200 {"v1", '1', 0, N_("Show v1 tables only."), 0, ARG_TYPE_NONE},
201 {"v2", '2', 0, N_("Show v2 and v3 tablesv only."), 0, ARG_TYPE_NONE}
202 };
203
204 static grub_err_t
205 grub_cmd_lsacpi (struct grub_extcmd_context *ctxt,
206 int argc __attribute__ ((unused)),
207 char **args __attribute__ ((unused)))
208 {
209 if (!ctxt->state[1].set)
210 {
211 struct grub_acpi_rsdp_v10 *rsdp1 = grub_acpi_get_rsdpv1 ();
212 if (!rsdp1)
213 grub_printf ("No RSDPv1\n");
214 else
215 {
216 grub_printf ("RSDPv1 signature:");
217 disp_acpi_rsdpv1 (rsdp1);
218 disp_acpi_rsdt_table ((void *) (grub_addr_t) rsdp1->rsdt_addr);
219 }
220 }
221
222 if (!ctxt->state[0].set)
223 {
224 struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 ();
225 if (!rsdp2)
226 grub_printf ("No RSDPv2\n");
227 else
228 {
229 #if GRUB_CPU_SIZEOF_VOID_P == 4
230 if (rsdp2->xsdt_addr >= (1ULL << 32))
231 grub_printf ("Unreachable RSDPv2\n");
232 else
233 #endif
234 {
235 grub_printf ("RSDPv2 signature:");
236 disp_acpi_rsdpv2 (rsdp2);
237 disp_acpi_xsdt_table ((void *) (grub_addr_t) rsdp2->xsdt_addr);
238 grub_printf ("\n");
239 }
240 }
241 }
242 return GRUB_ERR_NONE;
243 }
244
245 static grub_extcmd_t cmd;
246
247 GRUB_MOD_INIT(lsapi)
248 {
249 cmd = grub_register_extcmd ("lsacpi", grub_cmd_lsacpi, 0, "[-1|-2]",
250 N_("Show ACPI information."), options);
251 }
252
253 GRUB_MOD_FINI(lsacpi)
254 {
255 grub_unregister_extcmd (cmd);
256 }
257
258