1/** 2 * \file 3 * \brief ACPI RPC Client 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, 2009, 2011, 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, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <barrelfish/barrelfish.h> 16#include <barrelfish/caddr.h> 17#include <barrelfish/nameservice_client.h> 18 19#include <if/acpi_defs.h> 20#include <if/acpi_defs.h> 21 22#include <acpi_client/acpi_client.h> 23 24static struct acpi_connection { 25 bool is_done; 26 errval_t err; 27} state; 28 29static struct acpi_binding* binding; 30 31errval_t acpi_client_get_device_handle(const char *dev_id, 32 acpi_device_handle_t *ret_handle) 33{ 34 assert(binding != NULL); 35 errval_t err, msgerr; 36 err = binding->rpc_tx_vtbl.get_handle(binding, dev_id, ret_handle, &msgerr); 37 return err_is_fail(err) ? err : msgerr; 38} 39 40errval_t acpi_client_eval_integer(acpi_device_handle_t handle, 41 const char *path, uint64_t *data) 42{ 43 assert(binding != NULL); 44 errval_t err, msgerr; 45 err = binding->rpc_tx_vtbl.eval_integer(binding, handle, path, data, &msgerr); 46 return err_is_fail(err) ? err : msgerr; 47} 48 49 50errval_t acpi_reset(void) 51{ 52 assert(binding != NULL); 53 errval_t err, msgerr; 54 err = binding->rpc_tx_vtbl.reset(binding, &msgerr); 55 return err_is_fail(err) ? err : msgerr; 56} 57 58errval_t acpi_sleep(int st) 59{ 60 assert(binding != NULL); 61 errval_t err, msgerr; 62 err = binding->rpc_tx_vtbl.sleep(binding, st, &msgerr); 63 return err_is_fail(err) ? err : msgerr; 64} 65 66// Kludge for VBE driver 67errval_t acpi_get_vbe_bios_cap(struct capref *retcap, size_t *retsize) 68{ 69 assert(binding != NULL); 70 errval_t err, msgerr; 71 assert(retcap != NULL); 72 assert(retsize != NULL); 73 uint32_t s; 74 err = slot_alloc(retcap); 75 if (err_is_fail(err)) { 76 return err; 77 } 78 err = binding->rpc_tx_vtbl.get_vbe_bios_cap(binding, &msgerr, retcap, &s); 79 *retsize = s; 80 return err_is_fail(err) ? err : msgerr; 81} 82 83errval_t vtd_create_domain(struct capref pml4) 84{ 85 assert(binding != NULL); 86 errval_t err, msgerr; 87 err = binding->rpc_tx_vtbl.create_domain(binding, pml4, &msgerr); 88 return err_is_fail(err) ? err : msgerr; 89} 90 91errval_t vtd_delete_domain(struct capref pml4) 92{ 93 assert(binding != NULL); 94 errval_t err, msgerr; 95 err = binding->rpc_tx_vtbl.delete_domain(binding, pml4, &msgerr); 96 return err_is_fail(err) ? err : msgerr; 97} 98 99errval_t vtd_domain_add_device(int seg, int bus, int dev, int func, struct capref pml4) 100{ 101 assert(binding != NULL); 102 errval_t err, msgerr; 103 err = binding->rpc_tx_vtbl.vtd_add_device(binding, seg, bus, dev, func, pml4, &msgerr); 104 return err_is_fail(err) ? err : msgerr; 105} 106 107errval_t vtd_domain_remove_device(int seg, int bus, int dev, int func, struct capref pml4) 108{ 109 assert(binding != NULL); 110 errval_t err, msgerr; 111 err = binding->rpc_tx_vtbl.vtd_remove_device(binding, seg, bus, dev, func, pml4, &msgerr); 112 return err_is_fail(err) ? err : msgerr; 113} 114 115errval_t vtd_add_devices(void) 116{ 117 assert(binding != NULL); 118 errval_t err, msgerr; 119 err = binding->rpc_tx_vtbl.vtd_id_dom_add_devices(binding, &msgerr); 120 return err_is_fail(err) ? err : msgerr; 121} 122 123struct acpi_binding* get_acpi_binding(void) 124{ 125 assert(binding != NULL); 126 return binding; 127} 128 129static void rpc_bind_cb(void *st, errval_t err, struct acpi_binding* b) 130{ 131 if (err_is_ok(err)) { 132 binding = b; 133 acpi_rpc_client_init(binding); 134 } // else: Do nothing 135 136 assert(!state.is_done); 137 state.is_done = true; 138 state.err = err; 139} 140 141errval_t connect_to_acpi(void) 142{ 143 errval_t err; 144 iref_t iref; 145 146 err = nameservice_blocking_lookup("acpi", &iref); 147 if (err_is_fail(err)) { 148 return err; 149 } 150 151 state.is_done = false; 152 err = acpi_bind(iref, rpc_bind_cb, NULL, get_default_waitset(), 153 IDC_BIND_FLAGS_DEFAULT); 154 if (err_is_fail(err)) { 155 return err_push(err, FLOUNDER_ERR_BIND); 156 } 157 158 // Wait for callback to complete 159 while (!state.is_done) { 160 messages_wait_and_handle_next(); 161 } 162 163 return state.err; 164 165} 166