1/**
2 * \file
3 * \brief ACPI management
4 */
5
6/*
7 * Copyright (c) 2016 ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include <stdio.h>
16#include <barrelfish/barrelfish.h>
17#include <barrelfish/nameservice_client.h>
18#include <barrelfish_kpi/types.h>
19#include <acpi.h>
20#include <mm/mm.h>
21#include <octopus/getset.h>
22#include <octopus/barrier.h>
23#include <skb/skb.h>
24#include <pci/confspace/pci_confspace.h>
25#include "acpi_shared.h"
26#include "acpi_debug.h"
27#include "ioapic.h"
28#include <trace/trace.h>
29
30#include "pcilnk_controller_client.h"
31#include "ioapic_controller_client.h"
32
33// BIOS Copy
34struct capref biosmem;
35
36
37int acpi_arch_init(void)
38{
39    ACPI_STATUS as;
40
41    // find and init any embedded controller drivers
42    // we do this early, because control methods may need to access the EC space
43    ec_probe_ecdt();
44
45    as = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
46    if (ACPI_FAILURE(as)) {
47        ACPI_DEBUG("AcpiInitializeObjects failed\n");
48        return -1;
49    }
50
51    return 0;
52}
53
54errval_t acpi_arch_load_irq_routing_new(void){
55    // Load irq file
56    errval_t err;
57    err = skb_execute("[irq_routing_new].");
58    if (err_is_fail(err)) {
59        ACPI_DEBUG("Could not load irq_routing_new.pl.\n"
60               "SKB returned: %s\nSKB error: %s\n",
61                skb_get_output(), skb_get_error_output());
62        return err;
63    } else if(strstr(skb_get_error_output(), "library not found") != NULL) {
64        debug_printf("Error processing irq_routing_new.pl.\n"
65               "SKB stdout: %s\nSKB stderr: %s\n",
66                skb_get_output(), skb_get_error_output());
67        return SKB_ERR_EXECUTION;
68    } else {
69        ACPI_DEBUG("Successfully loaded irq_routing_new.pl.\n"
70               "SKB returned: %s\nSKB error: %s\n",
71                skb_get_output(), skb_get_error_output());
72        return SYS_ERR_OK;
73    }
74}
75
76errval_t acpi_arch_copy_bios_mem(void)
77{
78    errval_t err = SYS_ERR_OK;
79
80    // Get a copy of the VBE BIOS before ACPI touches it
81    struct capref bioscap;
82
83    err = mm_alloc_range(&pci_mm_physaddr, BIOS_BITS, 0,
84                       1UL << BIOS_BITS, &bioscap, NULL);
85    assert(err_is_ok(err));
86
87    void *origbios;
88    struct vregion *origbios_vregion;
89    err = vspace_map_one_frame(&origbios, 1 << BIOS_BITS, bioscap,
90                               NULL, &origbios_vregion);
91    assert(err_is_ok(err));
92
93    err = frame_alloc(&biosmem, 1 << BIOS_BITS, NULL);
94    assert(err_is_ok(err));
95
96    void *newbios;
97    struct vregion *newbios_vregion;
98    err = vspace_map_one_frame(&newbios, 1 << BIOS_BITS, biosmem,
99                               NULL, &newbios_vregion);
100    assert(err_is_ok(err));
101
102    memcpy(newbios, origbios, 1 << BIOS_BITS);
103
104    // Unmap both vspace regions again
105    vregion_destroy(origbios_vregion);
106    vregion_destroy(newbios_vregion);
107
108    err = mm_free(&pci_mm_physaddr, bioscap, 0, BIOS_BITS);
109    assert(err_is_ok(err));
110
111    return err;
112}
113
114
115errval_t acpi_arch_skb_set_info(void)
116{
117    errval_t err;
118    err = skb_add_fact("mem_region_type(%d,apic).", RegionType_LocalAPIC);
119    if (err_is_fail(err)) {
120        return err;
121    }
122
123    return skb_add_fact("mem_region_type(%d,ioapic).", RegionType_IOAPIC);
124}
125