1 /* ----------------------------------------------------------------------- *
3 * Copyright 2009 Erwan Velu - All Rights Reserved
5 * Permission is hereby granted, free of charge, to any person
6 * obtaining a copy of this software and associated documentation
7 * files (the "Software"), to deal in the Software without
8 * restriction, including without limitation the rights to use,
9 * copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom
11 * the Software is furnished to do so, subject to the following
14 * The above copyright notice and this permission notice shall
15 * be included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
26 * -----------------------------------------------------------------------
30 #include "hdt-common.h"
35 #include <acpi/acpi.h>
37 /* Print ACPI's table header in a defined formating */
38 static void show_header(void *address
, s_acpi_description_header
* h
)
40 more_printf("%-4s v%03x %-6s %-8s 0x%08x %-7s 0x%08x @ 0x%p\n",
41 h
->signature
, h
->revision
, h
->oem_id
, h
->oem_table_id
,
42 h
->oem_revision
, h
->creator_id
, h
->creator_revision
, address
)
45 /* That's an helper to visualize columns*/
46 static void show_table_separator(void)
49 ("----|----|------|--------|----------|-------|-----------|--------------------\n");
52 /* Display the main header before displaying the ACPI tables */
53 static void show_table_name(void)
56 ("ACPI rev oem table_id oem_rev creator creat_rev @ address \n");
57 show_table_separator();
60 /* called by "show acpi" */
61 void main_show_acpi(int argc __unused
, char **argv __unused
,
62 struct s_hardware
*hardware
)
66 if (hardware
->is_acpi_valid
== false) {
67 more_printf("No ACPI Tables detected\n");
73 /* RSDP tables aren't using the same headers as the other
74 * So let's use a dedicated rendering */
75 if (hardware
->acpi
.rsdp
.valid
) {
76 s_rsdp
*r
= &hardware
->acpi
.rsdp
;
78 ("RSDP v%03x %-6s @ %p\n",
79 r
->revision
, r
->oem_id
, r
->address
);
82 if (hardware
->acpi
.rsdt
.valid
)
83 show_header(hardware
->acpi
.rsdt
.address
,
84 &hardware
->acpi
.rsdt
.header
);
86 if (hardware
->acpi
.xsdt
.valid
)
87 show_header(hardware
->acpi
.xsdt
.address
,
88 &hardware
->acpi
.xsdt
.header
);
90 if (hardware
->acpi
.fadt
.valid
)
91 show_header(hardware
->acpi
.fadt
.address
, &hardware
->acpi
.fadt
.header
);
93 if (hardware
->acpi
.dsdt
.valid
)
94 show_header(hardware
->acpi
.dsdt
.address
, &hardware
->acpi
.dsdt
.header
);
96 /* SSDT includes many optional tables, let's display them */
97 for (int i
= 0; i
< hardware
->acpi
.ssdt_count
; i
++) {
98 if ((hardware
->acpi
.ssdt
[i
] != NULL
) && (hardware
->acpi
.ssdt
[i
]->valid
))
99 show_header(hardware
->acpi
.ssdt
[i
]->address
,
100 &hardware
->acpi
.ssdt
[i
]->header
);
103 if (hardware
->acpi
.sbst
.valid
)
104 show_header(hardware
->acpi
.sbst
.address
, &hardware
->acpi
.sbst
.header
);
106 if (hardware
->acpi
.ecdt
.valid
)
107 show_header(hardware
->acpi
.ecdt
.address
, &hardware
->acpi
.ecdt
.header
);
109 if (hardware
->acpi
.hpet
.valid
)
110 show_header(hardware
->acpi
.hpet
.address
, &hardware
->acpi
.hpet
.header
);
112 if (hardware
->acpi
.tcpa
.valid
)
113 show_header(hardware
->acpi
.tcpa
.address
, &hardware
->acpi
.tcpa
.header
);
115 if (hardware
->acpi
.mcfg
.valid
)
116 show_header(hardware
->acpi
.mcfg
.address
, &hardware
->acpi
.mcfg
.header
);
118 if (hardware
->acpi
.slic
.valid
)
119 show_header(hardware
->acpi
.slic
.address
, &hardware
->acpi
.slic
.header
);
121 if (hardware
->acpi
.boot
.valid
)
122 show_header(hardware
->acpi
.boot
.address
, &hardware
->acpi
.boot
.header
);
124 /* FACS isn't having the same headers, let's use a dedicated rendering */
125 if (hardware
->acpi
.facs
.valid
) {
126 s_facs
*fa
= &hardware
->acpi
.facs
;
132 if (hardware
->acpi
.madt
.valid
)
133 show_header(hardware
->acpi
.madt
.address
, &hardware
->acpi
.madt
.header
);
135 more_printf("\nLocal APIC at 0x%08x\n", hardware
->acpi
.madt
.local_apic_address
);
138 /* Let's display the Processor Local APIC configuration */
139 static void show_local_apic(s_madt
* madt
)
141 if (madt
->processor_local_apic_count
== 0) {
142 more_printf("No Processor Local APIC found\n");
146 /* For all detected logical CPU */
147 for (int i
= 0; i
< madt
->processor_local_apic_count
; i
++) {
148 s_processor_local_apic
*sla
= &madt
->processor_local_apic
[i
];
150 memset(buffer
, 0, sizeof(buffer
));
151 strcpy(buffer
, "disable");
152 /* Let's check if the flags reports the cpu as enabled */
153 if ((sla
->flags
& PROCESSOR_LOCAL_APIC_ENABLE
) ==
154 PROCESSOR_LOCAL_APIC_ENABLE
)
155 strcpy(buffer
, "enable");
156 more_printf("CPU #%u, LAPIC (acpi_id[0x%02x] apic_id[0x%02x]) %s\n",
157 sla
->apic_id
, sla
->acpi_id
, sla
->apic_id
, buffer
);
161 /* Display the local apic NMI configuration */
162 static void show_local_apic_nmi(s_madt
* madt
)
164 if (madt
->local_apic_nmi_count
== 0) {
165 more_printf("No Local APIC NMI found\n");
169 for (int i
= 0; i
< madt
->local_apic_nmi_count
; i
++) {
170 s_local_apic_nmi
*slan
= &madt
->local_apic_nmi
[i
];
172 more_printf("LAPIC_NMI (acpi_id[0x%02x] %s lint(0x%02x))\n",
173 slan
->acpi_processor_id
, flags_to_string(buffer
,
175 slan
->local_apic_lint
);
179 /* Display the IO APIC configuration */
180 static void show_io_apic(s_madt
* madt
)
182 if (madt
->io_apic_count
== 0) {
183 more_printf("No IO APIC found\n");
187 /* For all IO APICS */
188 for (int i
= 0; i
< madt
->io_apic_count
; i
++) {
189 s_io_apic
*sio
= &madt
->io_apic
[i
];
191 memset(buffer
, 0, sizeof(buffer
));
192 /* GSI base reports the GSI configuration
193 * Let's interpret it as string */
194 switch (sio
->global_system_interrupt_base
) {
196 strcpy(buffer
, "GSI 0-23");
199 strcpy(buffer
, "GSI 24-39");
202 strcpy(buffer
, "GSI 40-55");
205 strcpy(buffer
, "GSI Unknown");
209 more_printf("IO_APIC[%d] : apic_id[0x%02x] address[0x%08x] %s\n",
210 i
, sio
->io_apic_id
, sio
->io_apic_address
, buffer
);
214 /* Display the interrupt source override configuration */
215 static void show_interrupt_source_override(s_madt
* madt
)
217 if (madt
->interrupt_source_override_count
== 0) {
218 more_printf("No interrupt source override found\n");
222 /* Let's process each interrupt source override */
223 for (int i
= 0; i
< madt
->interrupt_source_override_count
; i
++) {
224 s_interrupt_source_override
*siso
= &madt
->interrupt_source_override
[i
];
227 memset(bus_type
, 0, sizeof(bus_type
));
228 /* Spec report bus type 0 as ISA */
230 strcpy(bus_type
, "ISA");
232 strcpy(bus_type
, "unknown");
234 more_printf("INT_SRC_OVR (bus %s (%d) bus_irq %d global_irq %d %s)\n",
235 bus_type
, siso
->bus
, siso
->source
,
236 siso
->global_system_interrupt
, flags_to_string(buffer
,
242 /* Display the apic configuration
243 * This is called by acpi> show apic */
244 static void show_acpi_apic(int argc __unused
, char **argv __unused
,
245 struct s_hardware
*hardware
)
247 if (hardware
->is_acpi_valid
== false) {
248 more_printf("No ACPI Tables detected\n");
252 s_madt
*madt
= &hardware
->acpi
.madt
;
254 if (madt
->valid
== false) {
255 more_printf("No APIC (MADT) table found\n");
259 more_printf("Local APIC at 0x%08x\n", madt
->local_apic_address
);
260 show_local_apic(madt
);
261 show_local_apic_nmi(madt
);
263 show_interrupt_source_override(madt
);
266 struct cli_callback_descr list_acpi_show_modules
[] = {
269 .exec
= show_acpi_apic
,
279 struct cli_module_descr acpi_show_modules
= {
280 .modules
= list_acpi_show_modules
,
281 .default_callback
= main_show_acpi
,
284 struct cli_mode_descr acpi_mode
= {
287 .default_modules
= NULL
,
288 .show_modules
= &acpi_show_modules
,