blob: a2ec2b03b39a1b4b24b1fa5454e61a2d9b216f90 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdio.h>
#include "init.h"
#define ACPI_MAX_INIT_TABLES 32
/* @brief Switch interrupts to APIC model (controls IRQ routing) */
static ACPI_STATUS set_apic_irq_mode(void) {
ACPI_OBJECT selector = {
.Integer.Type = ACPI_TYPE_INTEGER,
.Integer.Value = 1, // 1 means APIC mode according to ACPI v5 5.8.1
};
ACPI_OBJECT_LIST params = {
.Count = 1,
.Pointer = &selector,
};
return AcpiEvaluateObject(NULL, (char*)"\\_PIC", &params, NULL);
}
ACPI_STATUS init(void) {
// This sequence is described in section 10.1.2.1 (Full ACPICA Initialization)
// of the ACPICA developer's reference.
ACPI_STATUS status = AcpiInitializeSubsystem();
if (status != AE_OK) {
printf("WARNING: could not initialize ACPI\n");
return status;
}
status = AcpiInitializeTables(NULL, ACPI_MAX_INIT_TABLES, FALSE);
if (status == AE_NOT_FOUND) {
printf("WARNING: could not find ACPI tables\n");
return status;
} else if (status == AE_NO_MEMORY) {
printf("WARNING: could not initialize ACPI tables\n");
return status;
} else if (status != AE_OK) {
printf("WARNING: could not initialize ACPI tables for unknown reason\n");
return status;
}
status = AcpiLoadTables();
if (status != AE_OK) {
printf("WARNING: could not load ACPI tables: %d\n", status);
return status;
}
status = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION);
if (status != AE_OK) {
printf("WARNING: could not enable ACPI\n");
return status;
}
status = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
if (status != AE_OK) {
printf("WARNING: could not initialize ACPI objects\n");
return status;
}
status = set_apic_irq_mode();
if (status == AE_NOT_FOUND) {
printf("WARNING: Could not find ACPI IRQ mode switch\n");
} else if (status != AE_OK) {
printf("Failed to set APIC IRQ mode\n");
return status;
}
// TODO(teisenbe): Maybe back out of ACPI mode on failure, but we rely on
// ACPI for some critical things right now, so failure will likely prevent
// successful boot anyway.
return AE_OK;
}