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