---
i386/i386at/acpi_parse_apic.c | 203 --
i386/i386at/acpi_parse_apic.h | 18 ++-
i386/i386at/model_dep.c | 8 +-
3 files changed, 169 insertions(+), 60 deletions(-)
diff --git a/i386/i386at/acpi_parse_apic.c b/i386/i386at/acpi_parse_apic.c
index 9cd861ed..7b377d33 100644
--- a/i386/i386at/acpi_parse_apic.c
+++ b/i386/i386at/acpi_parse_apic.c
@@ -43,13 +43,12 @@ unsigned lapic_addr;
* and the number of entries stored in RSDT.
*/
void
-acpi_print_info(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, int
acpi_rsdt_n)
+acpi_print_info(phys_addr_t rsdp, void *rsdt, int acpi_rsdt_n)
{
printf("ACPI:\n");
-printf(" rsdp = %p; rsdp->rsdt_addr = %x\n", rsdp, rsdp->rsdt_addr);
-printf(" rsdt = %p; rsdt->length = %x (n = %x)\n", rsdt,
rsdt->header.length,
- acpi_rsdt_n);
+printf(" rsdp = 0x%lx\n", rsdp);
+printf(" rsdt/xsdt = 0x%p (n = %d)\n", rsdt, acpi_rsdt_n);
}
/*
@@ -99,27 +98,33 @@ acpi_check_signature(const uint8_t table_signature[], const
char *real_signature
*
* Preconditions: RSDP pointer must not be NULL.
*
- * Returns 0 if correct.
+ * Returns 1 if ACPI 1.0 and sets sdt_base
+ * Returns 2 if ACPI >= 2.0 and sets sdt_base
*/
static int8_t
-acpi_check_rsdp(struct acpi_rsdp *rsdp)
+acpi_check_rsdp(struct acpi_rsdp2 *rsdp, phys_addr_t *sdt_base)
{
-uint32_t checksum;
int is_rsdp;
/* Check if rsdp signature match with the ACPI RSDP signature. */
-is_rsdp = acpi_check_signature(rsdp->signature, ACPI_RSDP_SIG,
8*sizeof(uint8_t));
+is_rsdp = acpi_check_signature(rsdp->v1.signature, ACPI_RSDP_SIG,
8*sizeof(uint8_t));
if (is_rsdp != ACPI_SUCCESS)
return ACPI_BAD_SIGNATURE;
-/* If match, calculates rdsp checksum and check It. */
-checksum = acpi_checksum(rsdp, sizeof(struct acpi_rsdp));
-
-if (checksum != 0)
-return ACPI_BAD_CHECKSUM;
+if (rsdp->v1.revision == 0) {
+// ACPI 1.0
+*sdt_base = rsdp->v1.rsdt_addr;
+printf("ACPI v1.0\n");
+return 1;
+} else if (rsdp->v1.revision == 2) {
+// ACPI >= 2.0
+*sdt_base = rsdp->xsdt_addr;
+printf("ACPI >= v2.0\n");
+return 2;
+}
-return ACPI_SUCCESS;
+return ACPI_NO_RSDP;
}
/*
@@ -147,38 +152,43 @@ acpi_check_rsdp_align(void *addr)
*
* Preconditions: The start address (addr) must be aligned.
*
- * Returns the reference to rsdp structure if success, NULL if failure.
+ * Returns the physical address of rsdp structure if success, 0 if failure.
*/
-static struct acpi_rsdp*
-acpi_search_rsdp(void *addr, uint32_t length)
+static phys_addr_t
+acpi_search_rsdp(void *addr, uint32_t length, int *is_64bit)
{
void *end;
+int version = 0;
+phys_addr_t sdt_base = 0;
/* Search RDSP in memory space between addr and addr+lenght. */
for (end = addr+length; addr < end; addr += ACPI_RSDP_ALIGN) {
/* Check if the current memory block stores the RDSP. */
-if ((addr != NULL) && (acpi_check_rsdp(addr) == ACPI_SUCCESS)) {
-/* If yes, return RSDP address */
-return (struct acpi_rsdp*) addr;
+if ((addr != NULL) && ((version = acpi_check_rsdp(addr, &sdt_base)) >
0)) {
+/* If yes, return RSDT/XSDT address */
+*is_64bit = 0;
+if (version == 2)
+*is_64bit = 1;
+return sdt_base;
}
}
-return NULL;
+return 0;
}
/*
* acpi_get_rsdp: tries to find the RSDP table,
* searching It in many memory ranges, as It's written in ACPI Specification.
*
- * Returns the reference to RDSP structure if success, NULL if failure.
+ * Returns the reference to RDSP structure if success, 0 if failure.
*/
-static struct acpi_rsdp*
-acpi_get_rsdp(void)
+static phys_addr_t
+acpi_get_rsdp(int *is_64bit)
{
uint16_t *start = 0;
phys_addr_t base = 0;
-struct acpi_rsdp *rsdp = NULL;
+phys_addr_t rsdp = 0;
/* EDBA start address. */
start = (uint16_t*) phystokv(0x040e);
@@ -186,12 +196,12 @@ acpi_get_rsdp(void)
/* check alignment. */
if (acpi_check_rsdp_align((void *)base) == ACPI_BAD_ALIGN)
-return NULL;
-rsdp = acpi_search_rsdp((void *)base, 1024);
+return 0;
+rsdp = acpi_search_rsdp((void *)base, 1024, is_64bit);
-if (rsdp == NULL) {
+if (rsdp == 0) {
/* If RSDP isn't in EDBA, search in the BIOS read-only memory space
between 0Eh and 0Fh */
-rsdp = acpi_search_rsdp((void *)phystokv(0xe), 0x10 -
0x0e);
+rsdp = acpi_search_rsdp((void *)phystokv(0xe), 0x10 -
0x0e, is_64bit);
}
return rsdp;
@@ -229,16 +239,13 @@ acpi_check_rsdt(struct acpi_rsdt *rsdt)
* Returns the reference to RSDT table if success, NULL if error.
*/
static struct acpi_rsdt*
-acpi_get_rsdt(struct acpi_rsdp *rsdp, int* acpi_rsdt_n)
+acpi_get_rsdt(phys_addr_t rsdp_phys, int* acpi_rsdt_n)
{
-p