2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
3 $Id: acpi_tables.c,v 1.7 2004/01/07 07:13:03 nicja Exp $
7 #include "exec_intern.h"
10 #include <exec/lists.h>
11 #include <exec/types.h>
12 #include <exec/tasks.h>
13 #include <exec/execbase.h>
14 #include <aros/libcall.h>
15 #include <asm/segments.h>
17 #include <proto/kernel.h>
19 #include "kernel_intern.h"
21 /************************************************************************************************/
23 struct KernelACPIData _Kern_ACPIData
;
24 struct acpi_table_sdt KernACPISDTEntries
[ACPI_MAX_TABLES
];
25 char * KernACPISDTSigs
[ACPI_TABLE_COUNT
] =
47 Everything that doesnt work MUST be put on the OEMBlacklist!!!
48 If the problem is critical - mark it as such
51 enum acpi_oemblacklist_revisionmatch
56 greater_than_or_equal
,
59 struct acpi_oemblacklist_entry
63 unsigned int oem_revision
;
64 unsigned int acpi_tableid
;
65 enum acpi_oemblacklist_revisionmatch oem_revision_match
;
66 char *blacklist_reason
;
67 unsigned int blacklist_critical
;
70 struct acpi_oemblacklist_entry _ACPI_OEMBlacklist
[] =
73 {"ASUS ", "K7M ", 0x00001000, ACPI_DSDT
, less_than_or_equal
, "Field beyond end of region", 0},
76 {"ASUS\0\0", "P2B-S ", 0, ACPI_DSDT
, all_versions
, "Bogus PCI routing", 1},
78 /* Seattle 2 - old BIOS rev. */
79 {"INTEL ", "440BX ", 0x00001000, ACPI_DSDT
, less_than_or_equal
, "Field beyond end of region", 0},
81 /* Intel 810 Motherboard */
82 {"MNTRAL", "MO81010A", 0x00000012, ACPI_DSDT
, less_than_or_equal
, "Field beyond end of region", 0},
84 /* Compaq Presario 711FR */
85 {"COMAPQ", "EAGLES", 0x06040000, ACPI_DSDT
, less_than_or_equal
, "SCI issues (C2 disabled)", 0},
87 /* Compaq Presario 1700 */
88 {"PTLTD ", " DSDT ", 0x06040000, ACPI_DSDT
, less_than_or_equal
, "Multiple problems", 1},
90 /* Sony FX120, FX140, FX150? */
91 {"SONY ", "U0 ", 0x20010313, ACPI_DSDT
, less_than_or_equal
, "ACPI driver problem", 1},
93 /* Compaq Presario 800, Insyde BIOS */
94 {"INT440", "SYSFexxx", 0x00001001, ACPI_DSDT
, less_than_or_equal
, "Does not use _REG to protect EC OpRegions", 1},
96 /* IBM 600E - _ADR should return 7, but it returns 1 */
97 {"IBM ", "TP600E ", 0x00000105, ACPI_DSDT
, less_than_or_equal
, "Incorrect _ADR", 1},
99 /* Portege 7020, BIOS 8.10 */
100 {"TOSHIB", "7020CT ", 0x19991112, ACPI_DSDT
, all_versions
, "Implicit Return", 0},
103 {"TOSHIB", "4030 ", 0x19991112, ACPI_DSDT
, all_versions
, "Implicit Return", 0},
105 /* Portege 310/320, BIOS 7.1 */
106 {"TOSHIB", "310 ", 0x19990511, ACPI_DSDT
, all_versions
, "Implicit Return", 0},
111 /************************************************************************************************
112 ACPI RELATED FUNCTIONS
113 ************************************************************************************************/
115 /************************************************************************************************/
116 void core_ACPITableDump(IPTR dump_header
, IPTR dump_table
)
118 #warning "TODO: implement the table dump.."
123 * core_ACPITableHeaderEarly() .... used by both core_ACPIIsBlacklisted() and core_ACPITableSDTGet()
125 int core_ACPITableHeaderEarly(int id
, struct acpi_table_header
** header
)
128 struct acpi_table_sdt
*header_tmp
;
129 enum acpi_table_id temp_id
;
131 /* DSDT is different from the rest */
132 if (id
== ACPI_DSDT
) temp_id
= ACPI_FADT
;
135 /* Locate the table. */
136 for (i
= 0; i
< _Kern_ACPIData
.kb_ACPI_SDT_Count
; i
++)
138 header_tmp
= _Kern_ACPIData
.kb_ACPI_SDT_Entry
[i
];
139 if (header_tmp
->id
!= temp_id
)
142 *header
= header_tmp
->pa
;
145 rkprintf("[Kernel] core_ACPITableHeaderEarly: ERROR - table %s has bad pointer\n", KernACPISDTSigs
[id
]);
153 rkprintf("[Kernel] core_ACPITableHeaderEarly: WARNING - %s not present\n",
154 KernACPISDTSigs
[id
]);
160 /* Map the DSDT header via the pointer in the FADT */
161 struct acpi_table_fadt
*FADT
= (struct acpi_table_fadt
*)*header
;
163 *header
= FADT
->dsdt_addr
;
166 rkprintf("[Kernel] core_ACPITableHeaderEarly: ERROR - bad DSDT pointer\n");
174 /**********************************************************/
175 int core_ACPITableMADTFamParse(int id
, unsigned long madt_size
, int entry_id
, struct acpi_madt_entry_hook
* entry_handler
)
178 struct acpi_table_entry_header
*entry
= NULL
;
179 unsigned long count
= 0;
180 unsigned long madt_end
= 0;
182 struct acpi_table_sdt
*header_tmp
;
184 if ( !entry_handler
) return NULL
;
186 /* Locate the MADT (if exists). There should only be one. */
187 for (i
= 0; i
< _Kern_ACPIData
.kb_ACPI_SDT_Count
; i
++)
189 header_tmp
= _Kern_ACPIData
.kb_ACPI_SDT_Entry
[i
];
191 if ( header_tmp
->id
!= id
)
194 madt
= header_tmp
->pa
;
197 rkprintf("[Kernel] core_ACPITableMADTFamParse: ERROR - table %s has bad pointer\n", KernACPISDTSigs
[id
]);
205 rkprintf("[Kernel] core_ACPITableMADTFamParse: WARNING - %s not present\n", KernACPISDTSigs
[id
]);
209 madt_end
= (unsigned long)madt
+ header_tmp
->size
;
211 entry
= (struct acpi_table_entry_header
*)((unsigned long) madt
+ madt_size
);
213 /* Parse all entries looking for a match. */
214 while (((unsigned long)entry
) < madt_end
)
216 if (entry
->type
== entry_id
)
220 entry_handler
->header
= entry
;
221 AROS_UFC1(IPTR
, entry_handler
->h_Entry
, AROS_UFCA(struct Hook
*, entry_handler
, A0
));
223 entry
= (struct acpi_table_entry_header
*)((unsigned long)entry
+ entry
->length
);
229 /**********************************************************/
230 int core_ACPITableMADTParse(int id
, struct acpi_madt_entry_hook
* table_handler
)
232 return core_ACPITableMADTFamParse(ACPI_APIC
, sizeof(struct acpi_table_madt
), id
, table_handler
);
235 /**********************************************************/
236 int core_ACPITableParse(int id
, struct acpi_table_hook
* header_handler
)
240 struct acpi_table_sdt
*header_tmp
;
242 if ( !header_handler
) return NULL
;
244 for ( i
= 0; i
< _Kern_ACPIData
.kb_ACPI_SDT_Count
; i
++ )
246 header_tmp
= _Kern_ACPIData
.kb_ACPI_SDT_Entry
[i
];
248 if ( header_tmp
->id
!= id
) continue;
250 header_handler
->phys_addr
= header_tmp
->pa
;
251 header_handler
->size
= header_tmp
->size
;
252 AROS_UFC1 ( IPTR
, header_handler
->h_Entry
, AROS_UFCA(struct Hook
*, header_handler
, A0
) );
260 /**********************************************************/
261 IPTR
core_ACPITableSDTGet(struct acpi_table_rsdp
* RSDP
)
263 struct acpi_table_header
*header
= NULL
;
264 unsigned int i
, id
= 0;
266 if (!RSDP
) return NULL
;
268 /* First check XSDT (but only on ACPI 2.0-compatible systems) */
269 if ((RSDP
->revision
>= 2) && (((struct acpi20_table_rsdp
*)RSDP
)->xsdt_address
))
271 rkprintf("[Kernel] core_ACPITableSDTGet: Checking XSDT @ %p\n", RSDP
->rsdt_address
);
273 struct acpi_table_xsdt
*XSDT
= NULL
;
275 _Kern_ACPIData
.kb_ACPI_SDT_Phys
= ((struct acpi20_table_rsdp
*)RSDP
)->xsdt_address
;
277 XSDT
= (struct acpi_table_xsdt
*)_Kern_ACPIData
.kb_ACPI_SDT_Phys
;
280 rkprintf("[Kernel] core_ACPITableSDTGet: ERROR - bad XSDT pointer\n");
283 header
= &XSDT
->header
;
285 if (strncmp( header
->signature
, "XSDT", 4))
287 rkprintf("[Kernel] core_ACPITableSDTGet: ERROR - bad XSDT signature [header @ %p, sig='%4.4s']\n",header
,header
->signature
);
291 if (core_ACPITableChecksum(header
, header
->length
))
293 rkprintf("[Kernel] core_ACPITableSDTGet: ERROR - XSDT checksum invalid\n");
297 _Kern_ACPIData
.kb_ACPI_SDT_Count
= (header
->length
- sizeof(struct acpi_table_header
)) >> 3;
298 if (_Kern_ACPIData
.kb_ACPI_SDT_Count
> ACPI_MAX_TABLES
)
300 rkprintf("[Kernel] core_ACPITableSDTGet: WARNING - Truncated %lu XSDT entries\n", (_Kern_ACPIData
.kb_ACPI_SDT_Count
- ACPI_MAX_TABLES
));
301 _Kern_ACPIData
.kb_ACPI_SDT_Count
= ACPI_MAX_TABLES
;
304 for (i
= 0; i
< _Kern_ACPIData
.kb_ACPI_SDT_Count
; i
++)
306 _Kern_ACPIData
.kb_ACPI_SDT_Entry
[i
] = &KernACPISDTEntries
[i
];
307 ((struct acpi_table_sdt
*)_Kern_ACPIData
.kb_ACPI_SDT_Entry
[i
])->pa
= (unsigned long)XSDT
->entry
[i
];
310 else if (RSDP
->rsdt_address
)
312 /* If there is no XSDT, then check RSDT */
313 rkprintf("[Kernel] core_ACPITableSDTGet: Checking RSDT @ %p\n", RSDP
->rsdt_address
);
315 struct acpi_table_rsdt
*RSDT
= NULL
;
317 _Kern_ACPIData
.kb_ACPI_SDT_Phys
= RSDP
->rsdt_address
;
319 RSDT
= (struct acpi_table_rsdt
*)_Kern_ACPIData
.kb_ACPI_SDT_Phys
;
322 rkprintf("[Kernel] core_ACPITableSDTGet: ERROR - bad RSDT pointer\n");
325 header
= &RSDT
->header
;
327 if (strncmp(header
->signature
, "RSDT", 4))
329 rkprintf("[Kernel] core_ACPITableSDTGet: ERROR - bad RSDT signature [header @ %p, sig='%4.4s']\n",header
,header
->signature
);
333 if (core_ACPITableChecksum(header
, header
->length
))
335 rkprintf("[Kernel] core_ACPITableSDTGet: ERROR - RSDT checksum invalid\n");
339 _Kern_ACPIData
.kb_ACPI_SDT_Count
= (header
->length
- sizeof(struct acpi_table_header
)) >> 2;
340 if (_Kern_ACPIData
.kb_ACPI_SDT_Count
> ACPI_MAX_TABLES
)
342 rkprintf("[Kernel] core_ACPITableSDTGet: WARNING - Truncated %lu RSDT entries\n", (_Kern_ACPIData
.kb_ACPI_SDT_Count
- ACPI_MAX_TABLES
));
343 _Kern_ACPIData
.kb_ACPI_SDT_Count
= ACPI_MAX_TABLES
;
346 for (i
= 0; i
< _Kern_ACPIData
.kb_ACPI_SDT_Count
; i
++)
348 _Kern_ACPIData
.kb_ACPI_SDT_Entry
[i
] = &KernACPISDTEntries
[i
];
349 ((struct acpi_table_sdt
*)_Kern_ACPIData
.kb_ACPI_SDT_Entry
[i
])->pa
= (unsigned long)RSDT
->entry
[i
];
354 rkprintf("[Kernel] core_ACPITableSDTGet: No System Description Table (RSDT/XSDT) specified in RSDP\n");
358 core_ACPITableDump(header
, _Kern_ACPIData
.kb_ACPI_SDT_Phys
);
360 for (i
= 0; i
< _Kern_ACPIData
.kb_ACPI_SDT_Count
; i
++)
362 header
= (struct acpi_table_header
*)(((struct acpi_table_sdt
*)_Kern_ACPIData
.kb_ACPI_SDT_Entry
[i
])->pa
);
366 core_ACPITableDump(header
, ((struct acpi_table_sdt
*)_Kern_ACPIData
.kb_ACPI_SDT_Entry
[i
])->pa
);
368 if (core_ACPITableChecksum(header
, header
->length
))
370 rkprintf("[Kernel] core_ACPITableSDTGet: WARNING - SDT %d Checksum invalid\n", i
);
374 ((struct acpi_table_sdt
*)_Kern_ACPIData
.kb_ACPI_SDT_Entry
[i
])->size
= header
->length
;
376 /* Start at 1 to skip "unknown" */
377 for (id
= 1; id
< ACPI_TABLE_COUNT
; id
++)
379 if (!strncmp((char *)&header
->signature
, KernACPISDTSigs
[id
], sizeof(header
->signature
)))
381 ((struct acpi_table_sdt
*)_Kern_ACPIData
.kb_ACPI_SDT_Entry
[i
])->id
= id
;
386 /* We want to print the DSDT (because this is what people usually blacklist against),
387 but it is *not* in the RSDT. We don't know its phys_addr, so just print 0. */
389 if (!(core_ACPITableHeaderEarly(ACPI_DSDT
, &header
)))
391 core_ACPITableDump(header
, 0);
394 return _Kern_ACPIData
.kb_ACPI_SDT_Phys
;
397 /**********************************************************/
398 int core_ACPIIsBlacklisted()
402 struct acpi_table_header
*table_header
;
404 while (_ACPI_OEMBlacklist
[i
].oem_id
[0] != '\0')
406 if (core_ACPITableHeaderEarly(_ACPI_OEMBlacklist
[i
].acpi_tableid
, &table_header
))
412 if (strncmp(_ACPI_OEMBlacklist
[i
].oem_id
, table_header
->oem_id
, 6))
418 if (strncmp(_ACPI_OEMBlacklist
[i
].oem_table_id
, table_header
->oem_table_id
, 8))
424 if ((_ACPI_OEMBlacklist
[i
].oem_revision_match
== all_versions
) ||
425 ((_ACPI_OEMBlacklist
[i
].oem_revision_match
== less_than_or_equal
) &&
426 (table_header
->oem_revision
<= _ACPI_OEMBlacklist
[i
].oem_revision
)) ||
427 ((_ACPI_OEMBlacklist
[i
].oem_revision_match
== greater_than_or_equal
) &&
428 (table_header
->oem_revision
>= _ACPI_OEMBlacklist
[i
].oem_revision
)) ||
429 ((_ACPI_OEMBlacklist
[i
].oem_revision_match
== equal
) &&
430 (table_header
->oem_revision
== _ACPI_OEMBlacklist
[i
].oem_revision
)))
432 rkprintf("[Kernel] core_ACPIIsBlacklisted: ERROR - Vendor \"%6.6s\" System \"%8.8s\" Revision 0x%x has a known ACPI BIOS problem.\n",
433 _ACPI_OEMBlacklist
[i
].oem_id
, _ACPI_OEMBlacklist
[i
].oem_table_id
, _ACPI_OEMBlacklist
[i
].oem_revision
);
434 rkprintf("[Kernel] core_ACPIIsBlacklisted: ERROR - Reason: %s. This is a %s error\n",
435 _ACPI_OEMBlacklist
[i
].blacklist_reason
, ( _ACPI_OEMBlacklist
[i
].blacklist_critical
? "non-recoverable" : "recoverable" ));
437 blacklisted
= _ACPI_OEMBlacklist
[i
].blacklist_critical
;
446 ULONG
core_ACPIInitialise()
449 rkprintf("[Kernel] core_ACPIInitialise()\n");
451 struct acpi_table_hook ACPI_TableParse_MADT_hook
= {
452 .h_Entry
= (APTR
)ACPI_hook_Table_MADT_Parse
455 struct acpi_table_hook ACPI_TableParse_LAPIC_Addr_Ovr_hook
= {
456 .h_Entry
= (APTR
)ACPI_hook_Table_LAPIC_Addr_Ovr_Parse
459 struct acpi_table_hook ACPI_TableParse_LAPIC_hook
= {
460 .h_Entry
= (APTR
)ACPI_hook_Table_LAPIC_Parse
463 struct acpi_table_hook ACPI_TableParse_LAPIC_NMI_hook
= {
464 .h_Entry
= (APTR
)ACPI_hook_Table_LAPIC_NMI_Parse
467 struct acpi_table_hook ACPI_TableParse_IOAPIC_hook
= {
468 .h_Entry
= (APTR
)ACPI_hook_Table_IOAPIC_Parse
471 struct acpi_table_hook ACPI_TableParse_Int_Src_Ovr_hook
= {
472 .h_Entry
= (APTR
)ACPI_hook_Table_Int_Src_Ovr_Parse
475 struct acpi_table_hook ACPI_TableParse_NMI_Src_hook
= {
476 .h_Entry
= (APTR
)ACPI_hook_Table_NMI_Src_Parse
479 struct acpi_table_hook ACPI_TableParse_HPET_hook
= {
480 .h_Entry
= (APTR
)ACPI_hook_Table_HPET_Parse
483 /* MADT : If it exists, parse the Multiple APIC Description Table "MADT",
484 This table provides platform SMP configuration information [the successor to MPS tables] */
485 result
= core_ACPITableParse( ACPI_APIC
, &ACPI_TableParse_MADT_hook
);
486 rkprintf("[Kernel] core_ACPIInitialise: core_ACPITableParse(ACPI_APIC) returned %p\n", result
);
487 if ( !result
) return NULL
;
488 else if ( result
< 0 )
490 rkprintf("[Kernel] core_ACPIInitialise: ERROR - Error parsing MADT\n");
493 else if ( result
> 1 )
495 rkprintf("[Kernel] core_ACPIInitialise: WARNING - Multiple MADT tables exist\n");
498 /* Local APIC : The LAPIC address is obtained from the MADT (32-bit value)
499 and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). */
500 result
= core_ACPITableMADTParse( ACPI_MADT_LAPIC_ADDR_OVR
, &ACPI_TableParse_LAPIC_Addr_Ovr_hook
);
501 rkprintf("[Kernel] core_ACPIInitialise: core_ACPITableMADTParse(ACPI_MADT_LAPIC_ADDR_OVR) returned %p\n", result
);
504 rkprintf("[Kernel] core_ACPIInitialise: ERROR - Error parsing LAPIC address override entry\n");
508 result
= core_ACPITableMADTParse( ACPI_MADT_LAPIC
, &ACPI_TableParse_LAPIC_hook
);
509 rkprintf("[Kernel] core_ACPIInitialise: core_ACPITableMADTParse(ACPI_MADT_LAPIC) returned %p\n", result
);
512 #warning "TODO: Cleanup to allow fallback to MPS.."
513 rkprintf("[Kernel] core_ACPIInitialise: ERROR - No LAPIC entries present\n");
518 #warning "TODO: Cleanup to allow fallback to MPS.."
519 rkprintf("[Kernel] core_ACPIInitialise: ERROR - Error parsing LAPIC entry\n");
523 result
= core_ACPITableMADTParse( ACPI_MADT_LAPIC_NMI
, &ACPI_TableParse_LAPIC_NMI_hook
);
524 rkprintf("[Kernel] core_ACPIInitialise: core_ACPITableMADTParse(ACPI_MADT_LAPIC_NMI) returned %p\n", result
);
527 #warning "TODO: Cleanup to allow fallback to MPS.."
528 rkprintf("[Kernel] core_ACPIInitialise: ERROR - Error parsing LAPIC NMI entry\n");
532 _Kern_ACPIData
.kb_ACPI_LAPIC
= 1;
534 /* I/O APIC : ACPI interpreter is required to complete interrupt setup,
535 so if it is off, don't enumerate the io-apics with ACPI.
536 If MPS is present, it will handle them, otherwise the system will stay in PIC mode */
537 if (_Kern_ACPIData
.kb_ACPI_Disabled
|| !_Kern_ACPIData
.kb_ACPI_IRQ
) return 1;
539 result
= core_ACPITableMADTParse(ACPI_MADT_IOAPIC
, &ACPI_TableParse_IOAPIC_hook
);
540 rkprintf("[Kernel] core_ACPIInitialise: core_ACPITableMADTParse(ACPI_MADT_IOAPIC) returned %p\n", result
);
543 rkprintf("[Kernel] core_ACPIInitialise: ERROR - No IOAPIC entries present\n");
548 rkprintf("[Kernel] core_ACPIInitialise: ERROR - Error parsing IOAPIC entry\n");
552 /* Build a default routing table for legacy (ISA) interrupts. */
553 #warning "TODO: implement legacy irq config.."
554 // mp_config_acpi_legacy_irqs();
556 result
= core_ACPITableMADTParse(ACPI_MADT_INT_SRC_OVR
, &ACPI_TableParse_Int_Src_Ovr_hook
);
557 rkprintf("[Kernel] core_ACPIInitialise: core_ACPITableMADTParse(ACPI_MADT_INT_SRC_OVR) returned %p\n", result
);
560 #warning "TODO: Cleanup to allow fallback to MPS.."
561 rkprintf("[Kernel] core_ACPIInitialise: ERROR - Error parsing interrupt source overrides entry\n");
565 result
= core_ACPITableMADTParse(ACPI_MADT_NMI_SRC
, &ACPI_TableParse_NMI_Src_hook
);
566 rkprintf("[Kernel] core_ACPIInitialise: core_ACPITableMADTParse(ACPI_MADT_NMI_SRC) returned %p\n", result
);
569 #warning "TODO: Cleanup to allow fallback to MPS.."
570 rkprintf("[Kernel] core_ACPIInitialise: ERROR - Error parsing NMI SRC entry\n");
574 _Kern_ACPIData
.kb_APIC_IRQ_Model
= ACPI_IRQ_MODEL_IOAPIC
;
576 _Kern_ACPIData
.kb_ACPI_IOAPIC
= 1;
578 if ( _Kern_ACPIData
.kb_ACPI_LAPIC
&& _Kern_ACPIData
.kb_ACPI_IOAPIC
)
580 _Kern_ACPIData
.kb_SMP_Config
= 1;
581 rkprintf("[Kernel] core_ACPIInitialise: SMP Configured by APIC\n");
582 #warning "TODO: implement check for clustered apic's.."
583 //core_APICClusteredCheck();
586 core_ACPITableParse( ACPI_HPET
, &ACPI_TableParse_HPET_hook
);
589 } /* core_ACPIInit */
592 /**********************************************************/
593 IPTR
core_ACPIRootSystemDescriptionPointerScan(IPTR scan_start
, IPTR scan_length
)
595 unsigned long scan_offset
;
598 /* Scan for the Root System Description Pointer signature
599 on 16-byte boundaries of the physical memory region */
600 for (scan_offset
= 0; scan_offset
< scan_length
; scan_offset
+= 16)
602 scan_ptr
= scan_start
+ scan_offset
;
603 if ((scan_ptr
[0] != 'R') ||
604 (scan_ptr
[1] != 'S') ||
605 (scan_ptr
[2] != 'D') ||
606 (scan_ptr
[3] != ' ') ||
607 (scan_ptr
[4] != 'P') ||
608 (scan_ptr
[5] != 'T') ||
609 (scan_ptr
[6] != 'R') ||
610 (scan_ptr
[7] != ' '))
613 /* RSDP located, return its address */
620 /* Attempt to locate the ACPI Root System Description Pointer */
621 IPTR
core_ACPIRootSystemDescriptionPointerLocate()
623 IPTR RSDP_PhysAddr
= 0;
625 /* Search the first Kilobyte of the Extended BIOS Data Area */
626 if ((RSDP_PhysAddr
= core_ACPIRootSystemDescriptionPointerScan(0x00000000, 0x00000400)) == NULL
)
628 /* Search in BIOS ROM address space */
629 if ((RSDP_PhysAddr
= core_ACPIRootSystemDescriptionPointerScan(0x000E0000, 0x000FFFFF)) != NULL
)
631 rkprintf("[Kernel] core_ACPIRootSystemDescriptionPointerLocate: RSDP found in BIOS ROM space @ %p\n", RSDP_PhysAddr
);
636 rkprintf("[Kernel] core_ACPIRootSystemDescriptionPointerLocate: RSDP found in EBDA @ %p\n", RSDP_PhysAddr
);
639 return RSDP_PhysAddr
;
642 /**********************************************************/
643 int core_ACPITableChecksum(void * table_pointer
, unsigned long table_length
)
645 UBYTE
*tmp_pointer
= (UBYTE
*)table_pointer
;
646 unsigned long remains
= table_length
;
647 unsigned long sum
= 0;
649 if (!tmp_pointer
|| !table_length
) return NULL
;
651 while (remains
--) sum
+= *tmp_pointer
++;
656 /**********************************************************/
657 IPTR
core_ACPIProbe()
659 struct acpi_table_rsdp
*RSDP
;
663 rkprintf("[Kernel] core_ACPIProbe()\n");
665 /* Locate the Root System Description Table (RSDP) */
666 RSDP_PhysAddr
= core_ACPIRootSystemDescriptionPointerLocate();
667 if (RSDP_PhysAddr
!= NULL
)
669 RSDP
= RSDP_PhysAddr
;
670 rkprintf("[Kernel] core_ACPIProbe: Root System Description Pointer @ %p\n", RSDP
);
671 rkprintf("[Kernel] core_ACPIProbe: Root System Description Pointer [ v%3.3d '%6.6s' ]\n", RSDP
->revision
, RSDP
->oem_id
);
673 if (RSDP
->revision
>= 2) checksum
= core_ACPITableChecksum(RSDP
, ((struct acpi20_table_rsdp
*)RSDP
)->length
);
674 else checksum
= core_ACPITableChecksum(RSDP
, sizeof(struct acpi_table_rsdp
));
678 rkprintf("[Kernel] core_ACPIProbe: ERROR: Invalid RSDP checksum (%d)\n", checksum
);
682 /* Locate and map the System Description table (RSDT/XSDT) */
683 core_ACPITableSDTGet(RSDP
);
685 if (core_ACPIIsBlacklisted())
687 rkprintf("[Kernel] core_ACPIProbe: WARNING - BIOS listed in blacklist, disabling ACPI support\n");
693 rkprintf("[Kernel] core_ACPIProbe: Unable to locate RSDP - no ACPI\n");