blob: d6944bc2ce053f92458a759da74962825b32c015 [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.
#ifndef SRC_DEVICES_BOARD_DRIVERS_X86_INCLUDE_UTIL_H_
#define SRC_DEVICES_BOARD_DRIVERS_X86_INCLUDE_UTIL_H_
#include <zircon/compiler.h>
#include <zircon/types.h>
#include <acpica/acpi.h>
ACPI_STATUS acpi_evaluate_integer(ACPI_HANDLE handle, const char* name, uint64_t* out);
ACPI_STATUS acpi_evaluate_method_intarg(ACPI_HANDLE handle, const char* name, uint64_t arg);
// ACPI tables and objects in ACPI tables are identified using the their
// "signature" which is defined in section 5.2 of the ACPI specification as a
// "fixed length string". The majority of these signatures are 4 byte, non-null
// terminated, fixed length strings. The ACPICA library stores these signatures
// in their data structures as packed uint32_t's which are read from the tables
// in a little endian fashion.
//
// This effectively makes the signatures we need to deal with in ACPICA into
// FourCC codes
//
// https://en.wikipedia.org/wiki/FourCC
//
// Basically, 4 characters strings which are packed into and manipulated as
// integers. So, here we define a couple of utility functions that make it a
// bit easier to deal with these FourCC identifies in our code.
//
// make_fourcc allows us to build a FourCC in a constexpr fashion so that we can
// then easily test object names simply by saying something like
//
// if (obj->Name == make_fourcc('D', 'S', 'D', 'T')) { ... }
//
// For diagnostic and debug messages, it is frequently advantageous to have a
// properly null terminated string representation, but one which does not need
// to be heap allocated. For that, we haave fourcc_to_string which will pack
// the characters of a u32 FourCC into a 5-byte character array which can exist
// on the stack during a call to a logging function. For example
//
// zxlogf(INFO, "Found object %s", fourcc_to_string(obj->Name).str);
//
constexpr inline uint32_t make_fourcc(char a, char b, char c, char d) {
return ((static_cast<uint32_t>(d) & 0xFF) << 24) | ((static_cast<uint32_t>(c) & 0xFF) << 16) |
((static_cast<uint32_t>(b) & 0xFF) << 8) | (static_cast<uint32_t>(a) & 0xFF);
}
inline auto fourcc_to_string(uint32_t fourcc) {
struct Ret {
char str[5];
};
char a = static_cast<char>((fourcc >> 0) & 0xFF);
char b = static_cast<char>((fourcc >> 8) & 0xFF);
char c = static_cast<char>((fourcc >> 16) & 0xFF);
char d = static_cast<char>((fourcc >> 24) & 0xFF);
return Ret{.str = {isprint(a) ? a : '.', isprint(b) ? b : '.', isprint(c) ? c : '.',
isprint(d) ? d : '.', 0x00}};
}
#endif // SRC_DEVICES_BOARD_DRIVERS_X86_INCLUDE_UTIL_H_