1 /* ----------------------------------------------------------------------- *
3 * Copyright 2011 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 * -----------------------------------------------------------------------
29 #include "hdt-common.h"
32 void show_header(char *name
, void *address
, s_acpi_description_header
*h
, ZZJSON_CONFIG
*config
, ZZJSON
**item
)
34 char signature
[10]={0};
35 char revision
[10]={0};
36 char s_address
[16]={0};
38 char oem_table_id
[16]={0};
39 char oem_revision
[16]={0};
40 char creator_revision
[16]={0};
41 char creator_id
[16]={0};
42 snprintf(signature
,sizeof(signature
),"%s",h
->signature
);
43 snprintf(revision
,sizeof(revision
),"0x%03x",h
->revision
);
44 snprintf(oem_id
,sizeof(oem_id
),"%s",h
->oem_id
);
45 snprintf(oem_table_id
,sizeof(oem_table_id
),"%s",h
->oem_table_id
);
46 snprintf(creator_id
,sizeof(creator_id
),"%s",h
->creator_id
);
47 snprintf(oem_revision
,sizeof(oem_revision
),"0x%08x",h
->oem_revision
);
48 snprintf(creator_revision
,sizeof(creator_revision
),"0x%08x",h
->creator_revision
);
49 snprintf(s_address
,sizeof(s_address
),"%p",address
);
51 char address_name
[32]={0};
52 char signature_name
[32]={0};
53 char revision_name
[32]={0};
54 char oem_id_name
[32]={0};
55 char oem_table_id_name
[32]={0};
56 char oem_revision_name
[32]={0};
57 char creator_revision_name
[32]={0};
58 char creator_id_name
[32]={0};
59 snprintf(signature_name
,sizeof(signature_name
),"acpi.%s.signature",name
);
60 snprintf(revision_name
,sizeof(revision_name
),"acpi.%s.revision",name
);
61 snprintf(address_name
,sizeof(address_name
),"acpi.%s.address",name
);
62 snprintf(oem_id_name
,sizeof(oem_id_name
),"acpi.%s.oem_id",name
);
63 snprintf(oem_table_id_name
,sizeof(oem_table_id_name
),"acpi.%s.oem_table_id",name
);
64 snprintf(oem_revision_name
,sizeof(oem_revision_name
),"acpi.%s.oem_revision",name
);
65 snprintf(creator_revision_name
,sizeof(creator_revision_name
),"acpi.%s.creator_revision",name
);
66 snprintf(creator_id_name
,sizeof(creator_id_name
),"acpi.%s.creator_id",name
);
69 add_as(signature_name
,signature
)
70 add_as(revision_name
,revision
)
71 add_as(oem_id_name
,oem_id
)
72 add_as(oem_table_id_name
,oem_table_id
)
73 add_as(oem_revision_name
,oem_revision
)
74 add_as(creator_id_name
,creator_id
)
75 add_as(creator_revision_name
,creator_revision
)
76 add_as(address_name
,s_address
)
83 void dump_rsdt(s_acpi
* acpi
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
86 snprintf(valid
,sizeof(valid
),"%s","false");
87 if (acpi
->rsdt
.valid
) {
88 snprintf(valid
,sizeof(valid
),"%s","true");
91 add_as("acpi.item","rsdt")
92 add_as("acpi.rsdt.is_valid",valid
)
95 if (acpi
->rsdt
.valid
==false) {
100 show_header("rsdt",acpi
->rsdt
.address
, &acpi
->rsdt
.header
, config
, item
);
103 void dump_xsdt(s_acpi
* acpi
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
106 snprintf(valid
,sizeof(valid
),"%s","false");
107 if (acpi
->xsdt
.valid
) {
108 snprintf(valid
,sizeof(valid
),"%s","true");
111 add_as("acpi.item","xsdt")
112 add_as("acpi.xsdt.is_valid",valid
)
115 if (acpi
->xsdt
.valid
==false) {
120 show_header("xsdt",acpi
->xsdt
.address
, &acpi
->xsdt
.header
, config
, item
);
123 void dump_fadt(s_acpi
* acpi
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
126 snprintf(valid
,sizeof(valid
),"%s","false");
127 if (acpi
->rsdt
.valid
) {
128 snprintf(valid
,sizeof(valid
),"%s","true");
131 add_as("acpi.item","fadt")
132 add_as("acpi.fadt.is_valid",valid
)
135 if (acpi
->fadt
.valid
==false) {
140 show_header("fadt",acpi
->fadt
.address
, &acpi
->fadt
.header
, config
, item
);
143 void dump_dsdt(s_acpi
* acpi
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
146 snprintf(valid
,sizeof(valid
),"%s","false");
147 if (acpi
->dsdt
.valid
) {
148 snprintf(valid
,sizeof(valid
),"%s","true");
151 add_as("acpi.item","dsdt")
152 add_as("acpi.dsdt.is_valid",valid
)
155 if (acpi
->dsdt
.valid
==false) {
160 show_header("dsdt",acpi
->dsdt
.address
, &acpi
->dsdt
.header
, config
, item
);
163 void dump_sbst(s_acpi
* acpi
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
166 snprintf(valid
,sizeof(valid
),"%s","false");
167 if (acpi
->sbst
.valid
) {
168 snprintf(valid
,sizeof(valid
),"%s","true");
171 add_as("acpi.item","sbst")
172 add_as("acpi.sbst.is_valid",valid
)
175 if (acpi
->sbst
.valid
==false) {
180 show_header("sbst",acpi
->sbst
.address
, &acpi
->sbst
.header
, config
, item
);
183 void dump_ecdt(s_acpi
* acpi
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
186 snprintf(valid
,sizeof(valid
),"%s","false");
187 if (acpi
->ecdt
.valid
) {
188 snprintf(valid
,sizeof(valid
),"%s","true");
191 add_as("acpi.item","ecdt")
192 add_as("acpi.ecdt.is_valid",valid
)
195 if (acpi
->ecdt
.valid
==false) {
200 show_header("ecdt",acpi
->ecdt
.address
, &acpi
->ecdt
.header
, config
, item
);
203 void dump_hpet(s_acpi
* acpi
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
206 snprintf(valid
,sizeof(valid
),"%s","false");
207 if (acpi
->hpet
.valid
) {
208 snprintf(valid
,sizeof(valid
),"%s","true");
211 add_as("acpi.item","hpet")
212 add_as("acpi.hpet.is_valid",valid
)
215 if (acpi
->hpet
.valid
==false) {
220 show_header("hpet",acpi
->hpet
.address
, &acpi
->hpet
.header
, config
, item
);
223 void dump_tcpa(s_acpi
* acpi
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
226 snprintf(valid
,sizeof(valid
),"%s","false");
227 if (acpi
->tcpa
.valid
) {
228 snprintf(valid
,sizeof(valid
),"%s","true");
231 add_as("acpi.item","tcpa")
232 add_as("acpi.tcpa.is_valid",valid
)
235 if (acpi
->tcpa
.valid
==false) {
240 show_header("tcpa",acpi
->tcpa
.address
, &acpi
->tcpa
.header
, config
, item
);
243 void dump_mcfg(s_acpi
* acpi
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
246 snprintf(valid
,sizeof(valid
),"%s","false");
247 if (acpi
->mcfg
.valid
) {
248 snprintf(valid
,sizeof(valid
),"%s","true");
251 add_as("acpi.item","mcfg")
252 add_as("acpi.mcfg.is_valid",valid
)
255 if (acpi
->mcfg
.valid
==false) {
260 show_header("mcfg",acpi
->mcfg
.address
, &acpi
->mcfg
.header
, config
, item
);
263 void dump_slic(s_acpi
* acpi
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
266 snprintf(valid
,sizeof(valid
),"%s","false");
267 if (acpi
->slic
.valid
) {
268 snprintf(valid
,sizeof(valid
),"%s","true");
271 add_as("acpi.item","slic")
272 add_as("acpi.slic.is_valid",valid
)
275 if (acpi
->slic
.valid
==false) {
280 show_header("slic",acpi
->slic
.address
, &acpi
->slic
.header
, config
, item
);
284 void dump_boot(s_acpi
* acpi
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
287 snprintf(valid
,sizeof(valid
),"%s","false");
288 if (acpi
->boot
.valid
) {
289 snprintf(valid
,sizeof(valid
),"%s","true");
292 add_as("acpi.item","boot")
293 add_as("acpi.boot.is_valid",valid
)
296 if (acpi
->boot
.valid
==false) {
301 show_header("boot",acpi
->boot
.address
, &acpi
->boot
.header
, config
, item
);
304 void dump_madt(s_acpi
* acpi
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
307 snprintf(valid
,sizeof(valid
),"%s","false");
308 if (acpi
->madt
.valid
) {
309 snprintf(valid
,sizeof(valid
),"%s","true");
312 add_as("acpi.item","madt")
313 add_as("acpi.madt.is_valid",valid
)
316 if (acpi
->madt
.valid
==false) {
321 show_header("madt",acpi
->madt
.address
, &acpi
->madt
.header
, config
, item
);
324 void dump_ssdt(s_ssdt
*ssdt
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
327 snprintf(valid
,sizeof(valid
),"%s","false");
329 snprintf(valid
,sizeof(valid
),"%s","true");
332 add_as("acpi.item","ssdt")
333 add_as("acpi.ssdt.is_valid",valid
)
336 if (ssdt
->valid
==false) {
341 show_header("ssdt",ssdt
->address
, &ssdt
->header
, config
, item
);
344 void dump_rsdp(s_acpi
* acpi
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
347 snprintf(valid
,sizeof(valid
),"%s","false");
348 if (acpi
->rsdp
.valid
) {
349 snprintf(valid
,sizeof(valid
),"%s","true");
352 add_as("acpi.item","rsdp")
353 add_as("acpi.rsdp.is_valid",valid
)
356 if (acpi
->rsdp
.valid
==false) {
361 s_rsdp
*r
= &acpi
->rsdp
;
362 char revision
[10]={0};
363 char address
[16]={0};
365 snprintf(revision
,sizeof(revision
),"0x%03x",r
->revision
);
366 snprintf(address
,sizeof(address
),"%p",r
->address
);
367 snprintf(oem_id
,sizeof(oem_id
),"%s",r
->oem_id
);
369 add_as("acpi.rsdp.revision",revision
)
370 add_as("acpi.rsdp.oem_id",oem_id
)
371 add_as("acpi.rsdp.address",address
)
378 void dump_facs(s_acpi
* acpi
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
381 snprintf(valid
,sizeof(valid
),"%s","false");
382 if (acpi
->facs
.valid
) {
383 snprintf(valid
,sizeof(valid
),"%s","true");
386 add_as("acpi.item","facs")
387 add_as("acpi.facs.is_valid",valid
)
390 if (acpi
->facs
.valid
==false) {
395 s_facs
*fa
= &acpi
->facs
;
396 char address
[16]={0};
397 snprintf(address
,sizeof(address
),"%p",fa
->address
);
399 add_as("acpi.facs.address",address
)
406 void dump_interrupt_source_override(s_madt
* madt
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
409 add_as("acpi.item","interrupt_source_override")
410 add_ai("acpi.interrupt_source_override.count", madt
->interrupt_source_override_count
)
413 if (madt
->interrupt_source_override_count
== 0) {
418 /* Let's process each interrupt source override */
419 for (int i
= 0; i
< madt
->interrupt_source_override_count
; i
++) {
420 s_interrupt_source_override
*siso
= &madt
->interrupt_source_override
[i
];
421 char buffer
[20] = {0};
422 char bus_type
[10]= {0};
424 /* Spec report bus type 0 as ISA */
426 strcpy(bus_type
, "ISA");
428 strcpy(bus_type
, "unknown");
431 add_as("acpi.interrupt_source_override.bus_type",bus_type
)
432 add_ai("acpi.interrupt_source_override.bus",siso
->bus
)
433 add_ai("acpi.interrupt_source_override.bus_irq",siso
->source
)
434 add_ai("acpi.interrupt_source_override.global_irq",siso
->global_system_interrupt
)
435 add_as("acpi.interrupt_source_override.flags",flags_to_string(buffer
,siso
->flags
))
441 void dump_io_apic(s_madt
* madt
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
444 add_as("acpi.item","io_apic")
445 add_ai("acpi.io_apic.count", madt
->io_apic_count
)
448 if (madt
->io_apic_count
== 0) {
453 /* For all IO APICS */
454 for (int i
= 0; i
< madt
->io_apic_count
; i
++) {
455 s_io_apic
*sio
= &madt
->io_apic
[i
];
457 memset(buffer
, 0, sizeof(buffer
));
458 /* GSI base reports the GSI configuration
459 * Let's interpret it as string */
460 switch (sio
->global_system_interrupt_base
) {
462 strcpy(buffer
, "0-23");
465 strcpy(buffer
,"24-39");
468 strcpy(buffer
, "40-55");
471 strcpy(buffer
,"Unknown");
475 char apic_id
[16] = { 0 };
476 char address
[16] = { 0 };
477 snprintf(apic_id
,sizeof(apic_id
),"0x%02x",sio
->io_apic_id
);
478 snprintf(address
,sizeof(address
),"0x%08x",sio
->io_apic_address
);
480 add_ai("acpi.io_apic.number",i
)
481 add_as("acpi.io_apic.apic_id",apic_id
)
482 add_as("acpi.io_apic.adress",address
)
483 add_as("acpi.io_apic.gsi",buffer
)
489 void dump_local_apic_nmi(s_madt
* madt
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
492 add_as("acpi.item","local_apic_nmi")
493 add_ai("acpi.local_apic_nmi.count", madt
->local_apic_nmi_count
)
496 if (madt
->local_apic_nmi_count
== 0) {
501 for (int i
= 0; i
< madt
->local_apic_nmi_count
; i
++) {
502 s_local_apic_nmi
*slan
= &madt
->local_apic_nmi
[i
];
504 char acpi_id
[16] = { 0 };
505 char local_apic_lint
[16] = { 0 };
506 snprintf(acpi_id
, sizeof(acpi_id
), "0x%02x", slan
->acpi_processor_id
);
507 snprintf(local_apic_lint
, sizeof(local_apic_lint
), "0x%02x", slan
->local_apic_lint
);
509 add_as("acpi.processor_id", acpi_id
)
510 add_as("acpi.local_apic_nmi.flags", flags_to_string(buffer
,slan
->flags
))
511 add_as("acpi.local_apic_nmi.lint",local_apic_lint
)
518 void dump_local_apic(s_madt
* madt
, ZZJSON_CONFIG
* config
, ZZJSON
** item
)
520 char buffer
[16] = { 0 };
521 snprintf(buffer
, sizeof(buffer
), "0x%08x", madt
->local_apic_address
);
524 add_as("acpi.item","local_apic")
525 add_as("acpi.local_apic.address", buffer
)
526 add_ai("acpi.processor_local_apic.count", madt
->processor_local_apic_count
)
529 if (madt
->processor_local_apic_count
==0) {
534 /* For all detected logical CPU */
535 for (int i
= 0; i
< madt
->processor_local_apic_count
; i
++) {
536 s_processor_local_apic
*sla
= &madt
->processor_local_apic
[i
];
537 char lapic_status
[16] = { 0 };
538 char acpi_id
[16] = { 0 };
539 char apic_id
[16] = { 0 };
541 snprintf(lapic_status
,sizeof(lapic_status
),"%s","disabled");
542 /* Let's check if the flags reports the cpu as enabled */
543 if ((sla
->flags
& PROCESSOR_LOCAL_APIC_ENABLE
) ==
544 PROCESSOR_LOCAL_APIC_ENABLE
)
545 snprintf(lapic_status
,sizeof(lapic_status
),"%s","enabled");
546 snprintf(acpi_id
, sizeof(acpi_id
), "0x%02x", sla
->acpi_id
);
547 snprintf(apic_id
, sizeof(apic_id
), "0x%02x", sla
->apic_id
);
549 add_ai("acpi.cpu.apic_id", sla
->apic_id
)
550 add_as("acpi.cpu.apic_id (hex)", apic_id
)
551 add_as("acpi.cpu.acpi_id (hex)", acpi_id
)
552 add_as("acpi.lapic.enabled", lapic_status
)
558 void dump_acpi(struct s_hardware
*hardware
, ZZJSON_CONFIG
* config
,
562 add_hb(is_acpi_valid
);
563 if (hardware
->is_acpi_valid
== false)
566 s_madt
*madt
= &hardware
->acpi
.madt
;
567 add_b("acpi.apic.detected", madt
->valid
);
568 if (madt
->valid
== false) {
574 dump_local_apic(madt
, config
, item
);
575 dump_local_apic_nmi(madt
, config
, item
);
576 dump_io_apic(madt
, config
, item
);
577 dump_interrupt_source_override(madt
, config
, item
);
579 dump_rsdp(&hardware
->acpi
,config
,item
);
580 dump_rsdt(&hardware
->acpi
,config
,item
);
581 dump_xsdt(&hardware
->acpi
,config
,item
);
582 dump_fadt(&hardware
->acpi
,config
,item
);
583 dump_dsdt(&hardware
->acpi
,config
,item
);
584 dump_sbst(&hardware
->acpi
,config
,item
);
585 dump_ecdt(&hardware
->acpi
,config
,item
);
586 dump_hpet(&hardware
->acpi
,config
,item
);
587 dump_tcpa(&hardware
->acpi
,config
,item
);
588 dump_mcfg(&hardware
->acpi
,config
,item
);
589 dump_slic(&hardware
->acpi
,config
,item
);
590 dump_boot(&hardware
->acpi
,config
,item
);
591 dump_madt(&hardware
->acpi
,config
,item
);
592 for (int i
= 0; i
< hardware
->acpi
.ssdt_count
; i
++) {
593 if ((hardware
->acpi
.ssdt
[i
] != NULL
) && (hardware
->acpi
.ssdt
[i
]->valid
))
594 dump_ssdt(hardware
->acpi
.ssdt
[i
], config
, item
);
596 dump_facs(&hardware
->acpi
,config
,item
);