]> git.proxmox.com Git - grub2.git/blob - grub-core/commands/lsacpi.c
grub-mknetdir script.
[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 static void
29 print_strn (grub_uint8_t *str, grub_size_t len)
30 {
31 for (; *str && len; str++, len--)
32 grub_printf ("%c", *str);
33 for (len++; len; len--)
34 grub_printf (" ");
35 }
36
37 #define print_field(x) print_strn(x, sizeof (x))
38
39 static void
40 disp_acpi_table (struct grub_acpi_table_header *t)
41 {
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);
49 }
50
51 static void
52 disp_madt_table (struct grub_acpi_madt *t)
53 {
54 struct grub_acpi_madt_entry_header *d;
55 grub_uint32_t len;
56
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);
62 d = t->entries;
63 for (;len > 0; len -= d->len, d = (void *) ((grub_uint8_t *) d + d->len))
64 {
65 grub_printf (" type=%x l=%u ", d->type, d->len);
66
67 switch (d->type)
68 {
69 case GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE:
70 {
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,
74 dt->flags);
75 }
76 break;
77 case GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC:
78 {
79 struct grub_acpi_madt_entry_sapic *dt = (void *) d;
80 grub_printf ("IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T
81 "\n",
82 dt->id, dt->global_sys_interrupt_base,
83 dt->addr);
84 }
85 break;
86 case GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC:
87 {
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");
93 else
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,
97 dt->cpu_uid_str);
98 }
99 break;
100 case GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE:
101 {
102 struct grub_acpi_madt_entry_platform_int_source *dt = (void *) d;
103 static const char * const platint_type[] =
104 {"Nul", "PMI", "INIT", "CPEI"};
105
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,
111 dt->cpu_eid);
112 grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n",
113 dt->sapic_vector, dt->global_sys_int, dt->src_flags);
114 }
115 break;
116 default:
117 grub_printf (" ??\n");
118 }
119 }
120 }
121
122 static void
123 disp_acpi_xsdt_table (struct grub_acpi_table_header *t)
124 {
125 grub_uint32_t len;
126 grub_uint64_t *desc;
127
128 disp_acpi_table (t);
129 len = t->length - sizeof (*t);
130 desc = (grub_uint64_t *) (t + 1);
131 for (; len > 0; desc++, len -= sizeof (*desc))
132 {
133 if (sizeof (grub_addr_t) == 4 && *desc >= (1ULL << 32))
134 {
135 grub_printf ("Unreachable table\n");
136 continue;
137 }
138 t = (struct grub_acpi_table_header *) (grub_addr_t) *desc;
139
140 if (t == NULL)
141 continue;
142
143 if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE,
144 sizeof (t->signature)) == 0)
145 disp_madt_table ((struct grub_acpi_madt *) t);
146 else
147 disp_acpi_table (t);
148 }
149 }
150
151 static void
152 disp_acpi_rsdt_table (struct grub_acpi_table_header *t)
153 {
154 grub_uint32_t len;
155 grub_uint32_t *desc;
156
157 disp_acpi_table (t);
158 len = t->length - sizeof (*t);
159 desc = (grub_uint32_t *) (t + 1);
160 for (; len > 0; desc++, len -= sizeof (*desc))
161 {
162 t = (struct grub_acpi_table_header *) (grub_addr_t) *desc;
163
164 if (t == NULL)
165 continue;
166
167 if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE,
168 sizeof (t->signature)) == 0)
169 disp_madt_table ((struct grub_acpi_madt *) t);
170 else
171 disp_acpi_table (t);
172 }
173 }
174
175 static void
176 disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10 *rsdp)
177 {
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);
183 }
184
185 static void
186 disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp)
187 {
188 disp_acpi_rsdpv1 (&rsdp->rsdpv1);
189 grub_printf ("len=%d XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length,
190 rsdp->xsdt_addr);
191 }
192
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}
196 };
197
198 static grub_err_t
199 grub_cmd_lsacpi (struct grub_extcmd_context *ctxt,
200 int argc __attribute__ ((unused)),
201 char **args __attribute__ ((unused)))
202 {
203 if (!ctxt->state[1].set)
204 {
205 struct grub_acpi_rsdp_v10 *rsdp1 = grub_acpi_get_rsdpv1 ();
206 if (!rsdp1)
207 grub_printf ("No RSDPv1\n");
208 else
209 {
210 grub_printf ("RSDPv1 signature:");
211 disp_acpi_rsdpv1 (rsdp1);
212 disp_acpi_rsdt_table ((void *) (grub_addr_t) rsdp1->rsdt_addr);
213 }
214 }
215
216 if (!ctxt->state[0].set)
217 {
218 struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 ();
219 if (!rsdp2)
220 grub_printf ("No RSDPv2\n");
221 else
222 {
223 if (sizeof (grub_addr_t) == 4 && rsdp2->xsdt_addr >= (1ULL << 32))
224 grub_printf ("Unreachable RSDPv2\n");
225 else
226 {
227 grub_printf ("RSDPv2 signature:");
228 disp_acpi_rsdpv2 (rsdp2);
229 disp_acpi_xsdt_table ((void *) (grub_addr_t) rsdp2->xsdt_addr);
230 grub_printf ("\n");
231 }
232 }
233 }
234 return GRUB_ERR_NONE;
235 }
236
237 static grub_extcmd_t cmd;
238
239 GRUB_MOD_INIT(lsapi)
240 {
241 cmd = grub_register_extcmd ("lsacpi", grub_cmd_lsacpi, GRUB_COMMAND_FLAG_BOTH,
242 N_("[-1|-2]"),
243 N_("Show ACPI information."), options);
244 }
245
246 GRUB_MOD_FINI(lsacpi)
247 {
248 grub_unregister_extcmd (cmd);
249 }
250
251