Initial commit; kernel source import

This commit is contained in:
Nathan
2025-04-06 23:50:55 -05:00
commit 25c6d769f4
45093 changed files with 18199410 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
#
# DPTF Drivers
#
config INTEL_DPTF
tristate "Intel DPTF/ESIF Lower Framework"
select IOSF_MBI
depends on ACPI
---help---
This is a driver for DPTF/ESIF Lower Framework.
config INTEL_DPTF_ACPI
tristate "Intel DPTF Acpi Participant"
depends on INTEL_DPTF
---help---
This is a driver for DPTF Acpi Participant.
config INTEL_DPTF_CPU
tristate "Intel DPTF CPU Participant"
depends on INTEL_DPTF
---help---
This is a driver for DPTF CPU Participant.
config INTEL_DPTF_PCH
tristate "Intel DPTF PCH Participant"
depends on INTEL_DPTF
---help---
This is a driver for DPTF PCH Participant.

View File

@@ -0,0 +1,102 @@
################################################################################
## This file is provided under a dual BSD/GPLv2 license. When using or
## redistributing this file, you may do so under either license.
##
## GPL LICENSE SUMMARY
##
## Copyright (c) 2013 Intel Corporation All Rights Reserved
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of version 2 of the GNU General Public License as published by the
## Free Software Foundation.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
## FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, write to the Free Software Foundation, Inc.,
## 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
## The full GNU General Public License is included in this distribution in the
## file called LICENSE.GPL.
##
## BSD LICENSE
##
## Copyright (c) 2013 Intel Corporation All Rights Reserved
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions are met:
##
## * Redistributions of source code must retain the above copyright notice, this
## list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above copyright notice,
## this list of conditions and the following disclaimer in the documentation
## and/or other materials provided with the distribution.
## * Neither the name of Intel Corporation nor the names of its contributors may
## be used to endorse or promote products derived from this software without
## specific prior written permission.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
## ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
## LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
## POSSIBILITY OF SUCH DAMAGE.
##
################################################################################
obj-$(CONFIG_INTEL_DPTF) += esif_lf_driver.o
obj-$(CONFIG_INTEL_DPTF_ACPI) += dptf_acpi.o
obj-$(CONFIG_INTEL_DPTF_CPU) += dptf_cpu.o
obj-$(CONFIG_INTEL_DPTF_PCH) += dptf_pch.o
ccflags-y += -g
ccflags-y += -Wno-multichar -Wall
ccflags-y += -DESIF_ATTR_KERNEL
ccflags-y += -DESIF_ATTR_OS_LINUX
ccflags-y += -DESIF_ATTR_IOSF
# Participants (NATIVE CODE ONLY)
dptf_acpi-objs := dptf_acpi_os_lin.o
dptf_acpi-objs += esif_debug.o
dptf_cpu-objs := dptf_cpu_os_lin.o
dptf_cpu-objs += esif_debug.o
dptf_pch-objs := dptf_pch_os_lin.o
dptf_pch-objs += esif_debug.o
# OS Specific
esif_lf_driver-objs := esif_lf_os_lin.o
esif_lf_driver-objs += esif_ipc_os_lin.o
# Lower Framework R0
esif_lf_driver-objs += esif_lf.o
esif_lf_driver-objs += esif_lf_action.o
esif_lf_driver-objs += esif_lf_action_acpi.o
esif_lf_driver-objs += esif_lf_action_code.o
esif_lf_driver-objs += esif_lf_action_const.o
esif_lf_driver-objs += esif_lf_action_mbi.o
esif_lf_driver-objs += esif_lf_action_mmio.o
esif_lf_driver-objs += esif_lf_action_msr.o
esif_lf_driver-objs += esif_lf_action_systemio.o
esif_lf_driver-objs += esif_lf_action_var.o
esif_lf_driver-objs += esif_lf_command.o
esif_lf_driver-objs += esif_lf_cpc.o
esif_lf_driver-objs += esif_lf_data.o
esif_lf_driver-objs += esif_lf_dsp.o
esif_lf_driver-objs += esif_lf_event.o
esif_lf_driver-objs += esif_lf_pm.o
esif_lf_driver-objs += esif_lf_poll.o
esif_lf_driver-objs += esif_lf_primitive.o
# Common Framework
esif_lf_driver-objs += esif_debug.o
esif_lf_driver-objs += esif_hash_table.o
esif_lf_driver-objs += esif_ipc.o
esif_lf_driver-objs += esif_link_list.o
esif_lf_driver-objs += esif_queue.o

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,602 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#define ESIF_ATTR_OS_LINUX_DRIVER
#define DRIVER_NAME "dptf_acpi"
#include "esif_lf.h"
#define ESIF_DEBUG_MODULE ESIF_DEBUG_MOD_ACTION_ACPI
/* Event Receive */
static enum esif_rc acpi_recv_event(
enum esif_event_type type,
u16 domain,
struct esif_data *data_ptr
)
{
ESIF_TRACE_DEBUG("%s: domain %d %s(%d)\n",
ESIF_FUNC,
domain,
esif_event_type_str(type),
type);
return ESIF_OK;
}
/* ESIF Participant INTERFACE */
static struct esif_participant_iface pi_template = {
.version = ESIF_PARTICIPANT_VERSION,
.class_guid = ESIF_PARTICIPANT_ACPI_CLASS_GUID,
#ifndef ESIF_ATTR_PLATFORM
.enumerator = ESIF_PARTICIPANT_ENUM_ACPI,
#else
.enumerator = ESIF_PARTICIPANT_ENUM_PLAT,
#endif
.flags = 0x0,
.name = ESIF_PARTICIPANT_ACPI_NAME,
.desc = ESIF_PARTICIPANT_ACPI_DESC,
.driver_name = "?", /* Filled In Dynamically By Driver */
.device_name = "?", /* Filled In Dynamically By Driver */
.device_path = "NA", /* Filled In Dynamically By Driver */
.device = NULL, /* Driver Assigned */
.mem_base = NULL, /* Driver Assigned */
.mem_size = 0, /* Driver Assigned */
.acpi_handle = NULL, /* Driver Assigned */
/* EVENT */
.recv_event = acpi_recv_event,
.send_event = NULL, /* Filled In Dynamically By esif_lf */
/* ACPI */
.acpi_device = "?", /* Override From ACPI Name Space */
.acpi_scope = "?", /* Override From ACPI Name Space */
.acpi_uid = ESIF_PARTICIPANT_INVALID_UID,
.acpi_type = ESIF_PARTICIPANT_INVALID_TYPE,
/* PCI */
.pci_vendor = 0, /* Not Used */
.pci_device = 0, /* Not Used */
.pci_bus = 0, /* Not Used */
.pci_bus_device = 0, /* Not Used */
.pci_function = 0, /* Not Used */
.pci_revision = 0, /* Not Used */
.pci_class = 0, /* Not Used */
.pci_sub_class = 0, /* Not Used */
.pci_prog_if = 0 /* Not Used */
};
/*
******************************************************************************
* LINUX Driver Code Below Here. Implemetned As Platform Driver For
* Prototype to avoid the need for a CRB.
******************************************************************************
* Two Versions Can Be Built
* ACPI - Requires BIOS Expose DPTF ACPI Generic Sensors (under EC)
* Platform - Will Enum On Any Platform and Emulate HW
*/
/*
******************************************************************************
* PRIVATE
******************************************************************************
*/
/* Event Send Not Used Yet */
enum
esif_rc acpi_send_event(
struct esif_participant_iface *pi_ptr,
enum esif_event_type type,
u16 domain,
struct esif_data *data_ptr
)
{
if (NULL == pi_ptr)
return ESIF_E_PARAMETER_IS_NULL;
if (NULL == pi_ptr->send_event)
return ESIF_E_CALLBACK_IS_NULL;
return pi_ptr->send_event(pi_ptr, type, domain, data_ptr);
}
#ifndef ESIF_ATTR_PLATFORM
/* esif_acpi_ids pulled from autogen.h */
MODULE_DEVICE_TABLE(acpi, esif_acpi_ids);
/*
** ACPI Driver
*/
/* Add */
static int acpi_add(struct acpi_device *acpi_dev_ptr)
{
enum esif_rc rc = ESIF_OK;
char *kobj_path_ptr = NULL;
struct esif_participant_iface *pi_ptr = NULL;
struct device *dev_ptr = &acpi_dev_ptr->dev;
ESIF_TRACE_DEBUG("%s: acpi_dev %p, dev %p\n",
ESIF_FUNC,
acpi_dev_ptr,
dev_ptr);
if (NULL == acpi_dev_ptr || NULL == dev_ptr)
return -ESIF_E_NO_ACPI_SUPPORT;
pi_ptr = kzalloc(sizeof(struct esif_participant_iface), GFP_ATOMIC);
if (NULL == pi_ptr)
return -ENOMEM;
esif_ccb_memcpy(pi_ptr, &pi_template,
sizeof(struct esif_participant_iface));
dev_set_drvdata(dev_ptr, pi_ptr);
snprintf(pi_ptr->driver_name, ESIF_NAME_LEN, "%s.ko", DRIVER_NAME);
snprintf(pi_ptr->device_name, ESIF_NAME_LEN, "%s",
dev_name(&acpi_dev_ptr->dev));
kobj_path_ptr = kobject_get_path(&acpi_dev_ptr->dev.kobj, GFP_ATOMIC);
if (NULL != kobj_path_ptr) {
snprintf(pi_ptr->device_path, ESIF_PATH_LEN, "%s",
kobj_path_ptr);
kfree(kobj_path_ptr);
}
pi_ptr->device = &acpi_dev_ptr->dev;
pi_ptr->acpi_handle = acpi_dev_ptr->handle;
/* Grab Our Scope */
if (pi_ptr->acpi_handle) {
struct acpi_buffer acpi_scope = {
.length = ACPI_ALLOCATE_BUFFER};
acpi_status status = acpi_get_name(pi_ptr->acpi_handle,
ACPI_FULL_PATHNAME,
&acpi_scope);
if (ACPI_FAILURE(status)) {
ESIF_TRACE_DEBUG("%s: acpi_get_name error %d\n",
ESIF_FUNC,
status);
} else {
strncpy(pi_ptr->acpi_scope,
(char *)acpi_scope.pointer,
ESIF_SCOPE_LEN);
ESIF_TRACE_DEBUG("%s: scope = %s\n",
ESIF_FUNC,
pi_ptr->acpi_scope);
kfree(acpi_scope.pointer);
}
}
/* Now the _HID */
strncpy(pi_ptr->acpi_device, acpi_device_hid(
acpi_dev_ptr), ESIF_NAME_LEN);
/* Lookup Description Based On HID Maybe Replaced By _STR Later */
strncpy(pi_ptr->desc, esif_acpi_device_str(
pi_ptr->acpi_device), ESIF_DESC_LEN);
ESIF_TRACE_DEBUG("%s: _HID = %s\n", ESIF_FUNC, pi_ptr->acpi_device);
strncpy(pi_ptr->name, acpi_device_bid(acpi_dev_ptr), ESIF_NAME_LEN);
ESIF_TRACE_DEBUG("%s: temp name = %s\n", ESIF_FUNC, pi_ptr->name);
/* ACPI _STR */
if (pi_ptr->acpi_handle) {
struct acpi_buffer acpi_str = {.length = ACPI_ALLOCATE_BUFFER};
acpi_status status = acpi_evaluate_object(pi_ptr->acpi_handle,
"_STR",
NULL,
&acpi_str);
if (ACPI_FAILURE(status) || status == AE_NOT_FOUND) {
ESIF_TRACE_DEBUG(
"%s: acpi_evaluate_object(_STR) status %d\n",
ESIF_FUNC,
status);
} else {
union acpi_object *acpi_obj = acpi_str.pointer;
int len = acpi_obj->string.length / 2;
esif_ccb_uni2ascii(pi_ptr->desc,
ESIF_DESC_LEN,
acpi_obj->string.pointer,
len);
ESIF_TRACE_DEBUG("%s: desc = %s\n",
ESIF_FUNC,
pi_ptr->desc);
kfree(acpi_str.pointer);
}
}
/* ACPI _UID If Any */
if (pi_ptr->acpi_handle) {
struct acpi_buffer acpi_uid = {.length = ACPI_ALLOCATE_BUFFER};
acpi_status status = acpi_evaluate_object(pi_ptr->acpi_handle,
"_UID",
NULL,
&acpi_uid);
if (ACPI_FAILURE(status) || status == AE_NOT_FOUND) {
ESIF_TRACE_DEBUG(
"%s: acpi_evaluate_integer(_UID) status %d\n",
ESIF_FUNC,
status);
} else {
union acpi_object *acpi_obj = acpi_uid.pointer;
if (acpi_obj->type == ACPI_TYPE_STRING) {
esif_ccb_memcpy(pi_ptr->acpi_uid,
acpi_obj->string.pointer,
sizeof(pi_ptr->acpi_uid));
} else if (acpi_obj->type == ACPI_TYPE_INTEGER) {
esif_ccb_sprintf(sizeof(pi_ptr->acpi_uid),
pi_ptr->acpi_uid,
"%llx",
(u64) acpi_obj->integer.value);
};
ESIF_TRACE_DEBUG("%s: UID %s\n",
ESIF_FUNC,
pi_ptr->acpi_uid);
kfree(acpi_uid.pointer);
}
}
/* ACPI Intel PTYP */
if (pi_ptr->acpi_handle) {
struct acpi_buffer acpi_type = {.length = ACPI_ALLOCATE_BUFFER};
acpi_status status = acpi_evaluate_object(pi_ptr->acpi_handle,
"PTYP",
NULL,
&acpi_type);
if (ACPI_FAILURE(status) || status == AE_NOT_FOUND) {
ESIF_TRACE_DEBUG(
"%s: acpi_evaluate_integer(PTYP) status %d\n",
ESIF_FUNC,
status);
} else {
union acpi_object *acpi_obj = acpi_type.pointer;
pi_ptr->acpi_type = acpi_obj->integer.value;
ESIF_TRACE_DEBUG("%s: PTYPE %llu\n",
ESIF_FUNC,
(u64)pi_ptr->acpi_type);
kfree(acpi_type.pointer);
}
}
/* APCI Intel PGMB For PCI MMIO BAR */
if (pi_ptr->acpi_handle) {
struct acpi_buffer acpi_pgmb = {.length = ACPI_ALLOCATE_BUFFER};
acpi_status status = acpi_evaluate_object(pi_ptr->acpi_handle,
"PGMB",
NULL,
&acpi_pgmb);
if (ACPI_FAILURE(status) || status == AE_NOT_FOUND) {
ESIF_TRACE_DEBUG(
"%s: acpi_evaluate_integer(PGMB) status %d\n",
ESIF_FUNC,
status);
} else {
/* TODO works for mem but we need a way to get this */
u64 resource_len = 0x8000;
union acpi_object *acpi_obj = acpi_pgmb.pointer;
/* PGMB will return bits 38 To 15 only */
u64 phy_addr = ((u64)acpi_obj->integer.value);
ESIF_TRACE_DEBUG("%s: PGMB bits 35:18 %llx\n",
ESIF_FUNC,
phy_addr);
phy_addr <<= 15;
ESIF_TRACE_DEBUG("%s: PGMB phy_addr %llx\n",
ESIF_FUNC,
phy_addr);
ESIF_TRACE_DEBUG("%s: resource_len %llu\n",
ESIF_FUNC,
resource_len);
pi_ptr->mem_size = resource_len;
pi_ptr->mem_base = ioremap_nocache(phy_addr,
resource_len);
if (!pi_ptr->mem_base) {
ESIF_TRACE_ERROR("%s: failed to map iomem\n",
ESIF_FUNC);
}
ESIF_TRACE_DEBUG("%s: mem_base %p\n",
ESIF_FUNC,
pi_ptr->mem_base);
kfree(acpi_pgmb.pointer);
}
}
rc = esif_lf_register_participant(pi_ptr);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Remove */
#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 8, 0)
static int acpi_remove(struct acpi_device *acpi_dev_ptr, int type)
#else
static int acpi_remove(struct acpi_device *acpi_dev_ptr)
#endif
{
struct esif_participant_iface *pi_ptr = dev_get_drvdata(
&acpi_dev_ptr->dev);
enum esif_rc rc = esif_lf_unregister_participant(pi_ptr);
kfree(pi_ptr);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Event Notifier */
static void acpi_notify(
struct acpi_device *acpi_dev_ptr,
u32 event
)
{
struct esif_participant_iface *pi_ptr = dev_get_drvdata(
&acpi_dev_ptr->dev);
struct esif_data event_data = {
ESIF_DATA_UINT32, &event, sizeof(event), sizeof(event)};
ESIF_TRACE_DEBUG("%s: Non INT3400 devices, event %d\n", ESIF_FUNC,
event);
acpi_send_event(pi_ptr, ESIF_EVENT_ACPI, 'NA', &event_data);
}
/* ACPI Driver */
static struct acpi_driver acpi_driver = {
.name = DRIVER_NAME,
.class = "DptfAcpi",
.ids = esif_acpi_ids,
.ops = {
.add = acpi_add,
.remove = acpi_remove,
.notify = acpi_notify,
},
};
#else
/*
** Platform Bus Driver. Not Rentrant
*/
/* Probe */
static int acpi_platform_probe(struct platform_device *plat_dev_ptr)
{
enum esif_rc rc = ESIF_OK;
char *kobj_path_ptr = NULL;
struct device *dev_ptr = &plat_dev_ptr->dev;
ESIF_TRACE_DEBUG("%s: dev %p\n", ESIF_FUNC, plat_dev_ptr);
pi_template.device = dev_ptr;
dev_set_drvdata(dev_ptr, &pi_template);
snprintf(pi_template.driver_name, ESIF_NAME_LEN, "%s.ko", DRIVER_NAME);
snprintf(pi_template.device_name, ESIF_NAME_LEN, "%s",
dev_name(dev_ptr));
kobj_path_ptr = kobject_get_path(&dev_ptr->kobj, GFP_ATOMIC);
if (NULL != kobj_path_ptr) {
snprintf(pi_template.device_path,
ESIF_PATH_LEN,
"%s",
kobj_path_ptr);
kfree(kobj_path_ptr);
}
rc = esif_lf_register_participant(&pi_template);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Remove */
static int acpi_platform_remove(struct platform_device *plat_dev_ptr)
{
struct esif_participant_iface *pi_ptr = dev_get_drvdata(
&plat_dev_ptr->dev);
enum esif_rc rc = esif_lf_unregister_participant(pi_ptr);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, plat_dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Shutdown */
static void acpi_platform_shutdown(struct platform_device *plat_dev_ptr)
{
struct esif_participant_iface *pi_ptr = dev_get_drvdata(
&plat_dev_ptr->dev);
enum esif_rc rc = acpi_send_event(pi_ptr,
ESIF_EVENT_PARTICIPANT_RESUME,
'NA',
NULL);
ESIF_TRACE_DEBUG("%s dev %p rc = %d\n", ESIF_FUNC, plat_dev_ptr, rc);
rc = rc;/* Remove Compiler Warning */
}
/* Suspend */
static int acpi_platform_suspend(
struct platform_device *plat_dev_ptr,
pm_message_t state
)
{
struct esif_participant_iface *pi_ptr = dev_get_drvdata(
&plat_dev_ptr->dev);
enum esif_rc rc = acpi_send_event(pi_ptr,
ESIF_EVENT_PARTICIPANT_SUSPEND,
'NA',
NULL);
ESIF_TRACE_DEBUG("%s: dev %p %d\n", ESIF_FUNC, plat_dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Resume */
static int acpi_platform_resume(struct platform_device *plat_dev_ptr)
{
struct esif_participant_iface *pi_ptr = dev_get_drvdata(
&plat_dev_ptr->dev);
enum esif_rc rc = acpi_send_event(pi_ptr,
ESIF_EVENT_PARTICIPANT_RESUME,
'NA',
NULL);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, plat_dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Platform Driver */
static struct platform_driver platform_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
.probe = acpi_platform_probe,
.remove = acpi_platform_remove,
.shutdown = acpi_platform_shutdown,
.suspend = acpi_platform_suspend,
.resume = acpi_platform_resume
};
static struct platform_device *g_pd_ptr;
#endif
/* Load */
static int __init acpi_load(void)
{
int rc = 0;
ESIF_TRACE_INFO("%s: %s\n", ESIF_FUNC, ESIF_PARTICIPANT_ACPI_DESC);
ESIF_TRACE_INFO("%s: %s\n", ESIF_FUNC, ESIF_COPYRIGHT);
#ifndef ESIF_ATTR_PLATFORM
rc = acpi_bus_register_driver(&acpi_driver);
#else
rc = platform_driver_register(&platform_driver);
g_pd_ptr = platform_device_register_simple(DRIVER_NAME, 0, NULL, 0);
if (NULL == g_pd_ptr)
rc = -ENOMEM;
#endif
return rc;
}
/* Unload */
static void __exit acpi_unload(void)
{
ESIF_TRACE_INFO("%s: instance\n", ESIF_FUNC);
#ifndef ESIF_ATTR_PLATFORM
acpi_bus_unregister_driver(&acpi_driver);
#else
if (NULL != g_pd_ptr)
platform_device_unregister(g_pd_ptr);
platform_driver_unregister(&platform_driver);
#endif
}
/*
******************************************************************************
* PUBLIC
******************************************************************************
*/
/* Module Entry / Exit */
module_init(acpi_load);
module_exit(acpi_unload);
MODULE_VERSION(ESIF_VERSION);
MODULE_DESCRIPTION(ESIF_PARTICIPANT_ACPI_DESC);
MODULE_LICENSE(ESIF_LICENSE);
MODULE_AUTHOR(ESIF_AUTHOR);
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,640 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#define ESIF_ATTR_OS_LINUX_DRIVER
#define ESIF_DEBUG_MODULE ESIF_DEBUG_MOD_LINUX
#define DRIVER_NAME "dptf_cpu"
#include "esif_lf.h"
#include <linux/interrupt.h>
/* Event Receive */
static enum esif_rc cpu_recv_event(
enum esif_event_type type,
u16 domain,
struct esif_data *data_ptr
)
{
ESIF_TRACE_DEBUG("%s: event received domain %d type %d\n",
ESIF_FUNC,
domain,
type);
return ESIF_OK;
}
/* ESIF Particpant INTERFACE */
static struct esif_participant_iface pi = {
.version = ESIF_PARTICIPANT_VERSION,
.class_guid = ESIF_PARTICIPANT_CPU_CLASS_GUID,
#ifndef ESIF_ATTR_PLATFORM
.enumerator = ESIF_PARTICIPANT_ENUM_PCI,
#else /* ESIF_ATTR_PLATFORM */
.enumerator = ESIF_PARTICIPANT_ENUM_PLAT,
#endif
.flags = 0x0,
.name = ESIF_PARTICIPANT_CPU_NAME,
.desc = ESIF_PARTICIPANT_CPU_DESC,
.driver_name = "?", /* Filled In Dynamically By Driver */
.device_name = "?", /* Filled In Dynamically By Driver */
.device_path = "NA", /* Filled In Dynamically By Driver */
.device = NULL, /* Driver Assigned */
.mem_base = NULL, /* Driver Assigned */
.mem_size = 0, /* Driver Assigned */
.acpi_handle = NULL, /* Driver Assigned */
/* EVENT */
.recv_event = cpu_recv_event,
.send_event = NULL, /* Filled In Dynamically By esif_lf */
/* ACPI */
.acpi_device = "NA", /* NA For CPU Device */
.acpi_scope = "?", /* Override From ACPI Name Space */
.acpi_uid = ESIF_PARTICIPANT_INVALID_UID, /* NA For CPU Device */
.acpi_type = ESIF_PARTICIPANT_INVALID_TYPE, /* NA For CPU Device */
/* PCI */
.pci_vendor = 0, /* Filled In *Dynamically By *Driver */
.pci_device = 0, /* Filled In *Dynamically By *Driver */
.pci_bus = 0, /* Hardware Bus */
.pci_bus_device = 4, /* Hardware Device On Bus */
.pci_function = 0, /* Hardware Function Of Device On Bus */
.pci_revision = 0, /* Filled In Dynamically By Driver */
.pci_class = 0, /* Filled In Dynamically By Driver */
.pci_sub_class = 0, /* Filled In Dynamically By Driver */
.pci_prog_if = 0 /* Filled In Dynamically By Driver */
};
/*
******************************************************************************
* LINUX Driver Code Below Here. Implemetned As Platform Driver For
* Prototype to avoid the need for a CRB.
******************************************************************************
* Two Versions Can Be Built
* PCI - Requires Platform Hardware Support For Enum
* Platform - Will Enum On Any Platform and Emulate HW
*/
/*
*******************************************************************************
* PRIVATE
*******************************************************************************
*/
/* Event Send */
static enum
esif_rc cpu_send_event(
enum esif_event_type type,
u16 domain,
void *data_ptr
)
{
if (NULL == pi.send_event)
return ESIF_E_CALLBACK_IS_NULL;
return pi.send_event(&pi, type, domain, data_ptr);
}
#ifndef ESIF_ATTR_PLATFORM
/*
* PCI Bus Driver
*/
/* All 4-byte long, maybe identical accross CPUs */
#define THERMAL_CAMARILLO 0x5820 /* PACKAGE_THERMAL_CAMARILLO_INTERRUPT */
#define TEMP_TARGET 0x599c /* Thermal Monitor Ref Temp (Tjmax) in
* b[23:16] */
#define PKG_TEMP 0x5978 /* Package Temperature in b[7:0] */
#define PP0_TEMP 0x597c /* CPU Temperature in b[7:0] */
#define PP1_TEMP 0x5980 /* Gfx Temperature in b[7:0] */
#define THERMAL_CAMARILLO_STATUS 0x6200
/* esif_pci_cpu_ids pulled from autgen.h */
MODULE_DEVICE_TABLE(pci, esif_pci_cpu_ids);
/* Private data to keep */
struct cpu_priv_data {
u32 camarillo;
u32 tjmax;
};
static struct cpu_priv_data cpu_data;
static irqreturn_t pci_cpu_irq(
int irq,
void *devid
)
{
u32 val, temp;
struct pci_dev *dev_ptr = devid;
esif_ccb_mmio_read(pi.mem_base, PP0_TEMP, &temp);
ESIF_TRACE_DEBUG("%s: CPU Interrupt caught, curr temp is %d!!!\n",
ESIF_FUNC,
temp);
/*
* continuously sends unwarranted temperature threshold crossing
* rc = cpu_send_event(ESIF_EVENT_TYPE_TEMPERATURE_THRESHOLD, NULL);
*/
/*
* Camarillo status bit 7 and 9 indicate threshold 1 and 2 trip occured,
* once processed, these bits as well as PCI interrupt status register
* have to be cleared.
*/
esif_ccb_mmio_read(pi.mem_base, THERMAL_CAMARILLO_STATUS, &val);
if (val & 0x00000280) {
val &= 0xFFFFFD7F;
esif_ccb_mmio_write(pi.mem_base, THERMAL_CAMARILLO_STATUS, val);
pci_write_config_byte(dev_ptr, 0xdc, 0x01);
/* pci_cpu_init_aux(dev_ptr); */
}
return IRQ_HANDLED;
}
/* ACPI Send Event */
enum esif_rc acpi_send_event(
struct esif_participant_iface *pi_ptr,
enum esif_event_type type,
u16 domain,
struct esif_data *data_ptr
)
{
if (NULL == pi_ptr)
return ESIF_E_PARAMETER_IS_NULL;
if (NULL == pi_ptr->send_event)
return ESIF_E_CALLBACK_IS_NULL;
return pi_ptr->send_event(pi_ptr, type, domain, data_ptr);
}
/* ACPI Event Handler */
static void acpi_notify(acpi_handle handle, u32 event, void *data)
{
struct esif_participant_iface *pi_ptr = data;
struct esif_data event_data = {
ESIF_DATA_UINT32, &event, sizeof(event), sizeof(event)};
ESIF_TRACE_DEBUG("%s: ACPI event on CPU %d\n", ESIF_FUNC, event);
acpi_send_event(pi_ptr, ESIF_EVENT_ACPI, 'NA', &event_data);
}
/* Probe */
static int pci_cpu_probe(
struct pci_dev *dev_ptr,
const struct pci_device_id *dev_id_ptr
)
{
enum esif_rc rc = ESIF_OK;
char *kobj_path_ptr = NULL;
int err = 0;
int enabled = 0;
u64 resource_start;
u64 resource_len;
ESIF_TRACE_DEBUG("%s: dev %p pci_id %p pi %p\n",
ESIF_FUNC,
dev_ptr,
dev_id_ptr,
&pi);
pci_set_drvdata(dev_ptr, &pi);
/* Grab Linux Device Driver Not Platform Driver */
pi.device = &dev_ptr->dev;
snprintf(pi.driver_name, ESIF_NAME_LEN, "%s.ko", DRIVER_NAME);
snprintf(pi.device_name, ESIF_NAME_LEN, "%s", dev_name(&dev_ptr->dev));
kobj_path_ptr = kobject_get_path(&dev_ptr->dev.kobj, GFP_ATOMIC);
if (NULL != kobj_path_ptr) {
snprintf(pi.device_path, ESIF_PATH_LEN, "%s", kobj_path_ptr);
kfree(kobj_path_ptr);
}
err = pci_enable_device(dev_ptr);
if (err) {
ESIF_TRACE_ERROR("%s: failed to enable pci device\n",
ESIF_FUNC);
goto error_cleanup;
}
enabled = 1;
ESIF_TRACE_DEBUG("%s: pci device enabled\n", ESIF_FUNC);
resource_start = pci_resource_start(dev_ptr, 0);
if (!resource_start) {
ESIF_TRACE_ERROR("%s: failed to find iomem\n", ESIF_FUNC);
err = -ENOMEM;
goto error_cleanup;
}
ESIF_TRACE_DEBUG("%s: resource_start %llu\n", ESIF_FUNC,
resource_start);
resource_len = pci_resource_len(dev_ptr, 0);
ESIF_TRACE_DEBUG("%s: resource_len %llu\n", ESIF_FUNC, resource_len);
err = pci_request_regions(dev_ptr, DRIVER_NAME);
if (err) {
ESIF_TRACE_ERROR("%s: failed to request pci region\n",
ESIF_FUNC);
goto error_cleanup;
}
ESIF_TRACE_DEBUG("%s: have pci region\n", ESIF_FUNC);
err = request_irq(dev_ptr->irq,
pci_cpu_irq,
IRQF_SHARED,
DRIVER_NAME,
dev_ptr);
if (err) {
dev_err(&dev_ptr->dev, "fail to request irq %d\n", err);
goto error_cleanup;
}
ESIF_TRACE_DEBUG("%s: request_irq returns %d\n", ESIF_FUNC, err);
pi.mem_size = resource_len;
pi.mem_base = ioremap_nocache(resource_start, resource_len);
if (!pi.mem_base) {
err = -ENOMEM;
ESIF_TRACE_ERROR("%s: failed to map iomem\n", ESIF_FUNC);
goto error_cleanup;
}
ESIF_TRACE_DEBUG("%s: mem_base %p\n", ESIF_FUNC, pi.mem_base);
{
u8 *class_ptr = (u8 *)&dev_ptr->class;
pi.pci_vendor = dev_ptr->vendor;
pi.pci_device = dev_ptr->device;
pi.pci_revision = dev_ptr->revision;
pi.pci_class = *(class_ptr + 2);
pi.pci_sub_class = *(class_ptr + 1);
pi.pci_prog_if = *class_ptr;
}
/* Future */
switch (dev_ptr->device) {
default:
ESIF_TRACE_DEBUG("%s: %s cpu thermal device detected\n",
ESIF_FUNC, esif_device_str(dev_ptr->device));
break;
}
/* To use ACPI _TMP method, BIOS has to be enabled as temp reporting via
* EC.
* ACPI PATC/PATx aren't available for CPU participant anyway.
*/
pi.acpi_handle = DEVICE_ACPI_HANDLE(&dev_ptr->dev);
if (pi.acpi_handle) {
struct acpi_buffer acpi_scope = {
.length = ACPI_ALLOCATE_BUFFER};
acpi_status status = acpi_get_name(pi.acpi_handle,
ACPI_FULL_PATHNAME,
&acpi_scope);
ESIF_TRACE_DEBUG("%s: have acpi handle %p\n",
ESIF_FUNC,
pi.acpi_handle);
if (ACPI_FAILURE(status)) {
ESIF_TRACE_DEBUG("%s: acpi_get_name error %d\n",
ESIF_FUNC,
status);
} else {
strncpy(pi.acpi_scope,
acpi_scope.pointer,
ESIF_SCOPE_LEN);
ESIF_TRACE_DEBUG("%s: name = %s\n",
ESIF_FUNC,
pi.acpi_scope);
kfree(acpi_scope.pointer);
}
status = acpi_install_notify_handler(pi.acpi_handle,
ACPI_ALL_NOTIFY, acpi_notify, &pi);
if (ACPI_FAILURE(status))
ESIF_TRACE_DEBUG("%s: acpi_install_notify_handler error %d\n",
ESIF_FUNC, status);
}
/*
* Save orig camarillo and Tjmax before enabling thermal trip interrupt
* bits 15 & 23
*/
esif_ccb_mmio_read(pi.mem_base, THERMAL_CAMARILLO, &cpu_data.camarillo);
writel((cpu_data.camarillo | 0x00808000U),
(pi.mem_base + THERMAL_CAMARILLO));
esif_ccb_mmio_read(pi.mem_base, TEMP_TARGET, &cpu_data.tjmax);
cpu_data.tjmax = (cpu_data.tjmax >> 16) & 0x000000FF;
/* pci_cpu_init_aux(dev_ptr); */
rc = esif_lf_register_participant(&pi);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
error_cleanup:
if (enabled)
pci_disable_device(dev_ptr);
return err;
}
/* Remove */
static void pci_cpu_remove(struct pci_dev *dev_ptr)
{
enum esif_rc rc = ESIF_OK;
if (pi.acpi_handle)
acpi_remove_notify_handler(pi.acpi_handle, ACPI_ALL_NOTIFY,
acpi_notify);
writel(cpu_data.camarillo, (pi.mem_base + THERMAL_CAMARILLO));
rc = esif_lf_unregister_participant(&pi);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
free_irq(dev_ptr->irq, dev_ptr);
iounmap(pi.mem_base);
pci_release_region(dev_ptr, 0);
}
/* Shutdown */
static void pci_cpu_shutdown(struct pci_dev *dev_ptr)
{
enum esif_rc rc;
rc = cpu_send_event(ESIF_EVENT_PARTICIPANT_SHUTDOWN, 'NA', NULL);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
}
/* Suspend */
static int pci_cpu_suspend(
struct pci_dev *dev_ptr,
pm_message_t state
)
{
enum esif_rc rc;
rc = cpu_send_event(ESIF_EVENT_PARTICIPANT_SUSPEND, 'NA', &state);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Resume */
static int pci_cpu_resume(struct pci_dev *dev_ptr)
{
enum esif_rc rc;
rc = cpu_send_event(ESIF_EVENT_PARTICIPANT_RESUME, 'NA', NULL);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
static struct pci_driver pci_cpu_driver = {
.name = DRIVER_NAME,
.id_table = esif_pci_cpu_ids,
.probe = pci_cpu_probe,
.remove = pci_cpu_remove,
.shutdown = pci_cpu_shutdown,
.suspend = pci_cpu_suspend,
.resume = pci_cpu_resume
};
#else /* ESIF_ATTR_PLATFORM */
/*
* Platform Bus Driver
*/
/* Probe */
static int platform_cpu_probe(struct platform_device *dev_ptr)
{
enum esif_rc rc = ESIF_OK;
char *kobj_path_ptr = NULL;
ESIF_TRACE_DEBUG("%s: dev %p\n", ESIF_FUNC, dev_ptr);
/* Grab Linux Device Driver Not Platform Driver */
pi.device = &dev_ptr->dev;
snprintf(pi.driver_name, ESIF_NAME_LEN, "%s.ko", DRIVER_NAME);
snprintf(pi.device_name, ESIF_NAME_LEN, "%s", dev_name(&dev_ptr->dev));
kobj_path_ptr = kobject_get_path(&dev_ptr->dev.kobj, GFP_ATOMIC);
if (NULL != kobj_path_ptr) {
snprintf(pi.device_path, ESIF_PATH_LEN, "%s", kobj_path_ptr);
kfree(kobj_path_ptr);
}
rc = esif_lf_register_participant(&pi);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Remove */
static int platform_cpu_remove(struct platform_device *dev_ptr)
{
enum esif_rc rc;
rc = esif_lf_unregister_participant(&pi);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Shutdown */
static void platform_cpu_shutdown(struct platform_device *dev_ptr)
{
enum esif_rc rc;
rc = cpu_send_event(ESIF_EVENT_PARTICIPANT_RESUME, 'NA', NULL);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
}
/* Suspend */
static int platform_cpu_suspend(
struct platform_device *dev_ptr,
pm_message_t state
)
{
enum esif_rc rc;
rc = cpu_send_event(ESIF_EVENT_PARTICIPANT_SUSPEND, 'NA', &state);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Resume */
static int platform_cpu_resume(struct platform_device *dev_ptr)
{
enum esif_rc rc;
rc = cpu_send_event(ESIF_EVENT_PARTICIPANT_RESUME, 'NA', NULL);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Platform Driver */
static struct platform_driver platform_cpu_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
.probe = platform_cpu_probe,
.remove = platform_cpu_remove,
.shutdown = platform_cpu_shutdown,
.suspend = platform_cpu_suspend,
.resume = platform_cpu_resume
};
static struct platform_device *g_pd_ptr;
#endif
/* Load */
static int __init dptf_cpu_load(void)
{
int rc = 0;
ESIF_TRACE_INFO("%s: %s\n", ESIF_FUNC, ESIF_PARTICIPANT_CPU_DESC);
ESIF_TRACE_INFO("%s: %s\n", ESIF_FUNC, ESIF_COPYRIGHT);
#ifndef ESIF_ATTR_PLATFORM
rc = pci_register_driver(&pci_cpu_driver);
#else /* ESIF_ATTR_PLATFORM */
ESIF_TRACE_INFO("%s: %s\n", ESIF_FUNC, ESIF_PLATFORM_MSG);
rc = platform_driver_register(&platform_cpu_driver);
/* Simulate Device Insert */
g_pd_ptr = platform_device_register_simple(DRIVER_NAME, 0, NULL, 0);
if (NULL == g_pd_ptr)
rc = -ENOMEM;
#endif
return rc;
}
/* Unload */
static void __exit dptf_cpu_unload(void)
{
/* Simulate Device Removal */
#ifndef ESIF_ATTR_PLATFORM
pci_unregister_driver(&pci_cpu_driver);
#else /* ESIF_ATTR_PLATFORM */
if (NULL != g_pd_ptr)
platform_device_unregister(g_pd_ptr);
platform_driver_unregister(&platform_cpu_driver);
#endif
}
/*
*******************************************************************************
* PUBLIC
*******************************************************************************
*/
/* Module Entry / Exit */
module_init(dptf_cpu_load);
module_exit(dptf_cpu_unload);
MODULE_VERSION(ESIF_VERSION);
MODULE_DESCRIPTION(ESIF_PARTICIPANT_CPU_DESC);
MODULE_LICENSE(ESIF_LICENSE);
MODULE_AUTHOR(ESIF_AUTHOR);
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,548 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#define ESIF_ATTR_OS_LINUX_DRIVER
#define ESIF_DEBUG_MODULE ESIF_DEBUG_MOD_LINUX
#define DRIVER_NAME "dptf_pch"
#include "esif_lf.h"
/* Event Receive */
static enum esif_rc pch_recv_event(
enum esif_event_type type,
u16 domain,
struct esif_data *data_ptr
)
{
ESIF_TRACE_DEBUG("%s: event received %d\n", ESIF_FUNC, type);
return ESIF_OK;
}
/* ESIF Particpant INTERFACE */
static struct esif_participant_iface pi = {
.version = ESIF_PARTICIPANT_VERSION,
.class_guid = ESIF_PARTICIPANT_PCH_CLASS_GUID,
#ifndef ESIF_ATTR_PLATFORM
.enumerator = ESIF_PARTICIPANT_ENUM_PCI,
#else /* ESIF_ATTR_PLATFORM */
.enumerator = ESIF_PARTICIPANT_ENUM_PLAT,
#endif
.flags = 0x0,
.name = ESIF_PARTICIPANT_PCH_NAME,
.desc = ESIF_PARTICIPANT_PCH_DESC,
.driver_name = "?", /* Filled In Dynamically By Driver */
.device_name = "?", /* Filled In Dynamically By Driver */
.device_path = "NA", /* Filled In Dynamically By Driver */
.device = NULL, /* Driver Assigned */
.mem_base = NULL, /* Driver Assigned */
.mem_size = 0, /* Driver Assigned */
.acpi_handle = NULL, /* Driver Assigned */
/* EVENT */
.recv_event = pch_recv_event,
.send_event = NULL, /* Filled In Dynamically By esif_lf */
/* ACPI */
.acpi_device = "NA", /* NA For PCH Device */
.acpi_scope = "?", /* Filled In Dynamically By Driver */
.acpi_uid = ESIF_PARTICIPANT_INVALID_UID, /* NA For PCH Device */
.acpi_type = ESIF_PARTICIPANT_INVALID_TYPE, /* NA For PCH Device */
/* PCI */
.pci_vendor = 0, /* Filled In Dynamically By Driver */
.pci_device = 0, /* Filled In Dynamically By Driver */
.pci_bus = 0x0, /* Hardware Bus */
.pci_bus_device = 0x1f, /* Hardware Device On Bus */
.pci_function = 0x6, /* Hardware Function Of Device On Bus */
.pci_revision = 0, /* Filled In Dynamically By Driver */
.pci_class = 0, /* Filled In Dynamically By Driver */
.pci_sub_class = 0, /* Filled In Dynamically By Driver */
.pci_prog_if = 0 /* Filled In Dynamically By Driver */
};
/*
******************************************************************************
* LINUX Driver Code Below Here. Implemetned As Platform Driver For
* Prototype to avoid the need for a CRB.
*******************************************************************************
* Two Versions Can Be Built
* PCI - Requires Platform Hardware Support For Enum
* Platform - Will Enum On Any Platform and Emulate HW
*/
/*
******************************************************************************
* PRIVATE
******************************************************************************
*/
/* Event Send */
static enum esif_rc pch_send_event(
enum esif_event_type type,
u16 domain,
void *data_ptr
)
{
if (NULL == pi.send_event)
return ESIF_E_CALLBACK_IS_NULL;
return pi.send_event(&pi, type, domain, data_ptr);
}
#ifndef ESIF_ATTR_PLATFORM
/*
* PCI Bus Driver
*/
/* esif_pci_pch_ids pulled from autogen.h */
MODULE_DEVICE_TABLE(pci, esif_pci_pch_ids);
/* ACPI Send Event */
enum esif_rc acpi_send_event(
struct esif_participant_iface *pi_ptr,
enum esif_event_type type,
u16 domain,
struct esif_data *data_ptr
)
{
if (NULL == pi_ptr)
return ESIF_E_PARAMETER_IS_NULL;
if (NULL == pi_ptr->send_event)
return ESIF_E_CALLBACK_IS_NULL;
return pi_ptr->send_event(pi_ptr, type, domain, data_ptr);
}
/* ACPI Event Handler */
static void acpi_notify(acpi_handle handle, u32 event, void *data)
{
struct esif_participant_iface *pi_ptr = data;
struct esif_data event_data = {
ESIF_DATA_UINT32, &event, sizeof(event), sizeof(event)};
ESIF_TRACE_DEBUG("%s: ACPI event on PCH %d\n", ESIF_FUNC, event);
acpi_send_event(pi_ptr, ESIF_EVENT_ACPI, 'NA', &event_data);
}
/* Probe */
static int pci_pch_probe(
struct pci_dev *dev_ptr,
const struct pci_device_id *dev_id_ptr
)
{
enum esif_rc rc = ESIF_OK;
char *kobj_path_ptr = NULL;
int err = 0;
int enabled = 0;
u64 resource_start; /* memory/io resource start */
u64 resource_len; /* memory/io resource length */
ESIF_TRACE_DEBUG("%s: dev %p pci_id %p\n",
ESIF_FUNC,
dev_ptr,
dev_id_ptr);
/* Grab Linux Device Driver Not Platform Driver */
pi.device = &dev_ptr->dev;
snprintf(pi.driver_name, ESIF_NAME_LEN, "%s.ko", DRIVER_NAME);
snprintf(pi.device_name, ESIF_NAME_LEN, "%s", dev_name(&dev_ptr->dev));
kobj_path_ptr = kobject_get_path(&dev_ptr->dev.kobj, GFP_ATOMIC);
if (NULL != kobj_path_ptr) {
snprintf(pi.device_path, ESIF_PATH_LEN, "%s", kobj_path_ptr);
kfree(kobj_path_ptr);
}
err = pci_enable_device(dev_ptr);
if (err) {
ESIF_TRACE_ERROR("%s: failed to enable pci device\n",
ESIF_FUNC);
goto error_cleanup;
}
enabled = 1;
ESIF_TRACE_DEBUG("%s: pci device enabled\n", ESIF_FUNC);
resource_start = pci_resource_start(dev_ptr, 0);
if (!resource_start) {
ESIF_TRACE_ERROR("%s: failed to find iomem\n", ESIF_FUNC);
err = -ENOMEM;
goto error_cleanup;
}
ESIF_TRACE_DEBUG("%s: resource_start %llu\n", ESIF_FUNC,
resource_start);
resource_len = pci_resource_len(dev_ptr, 0);
ESIF_TRACE_DEBUG("%s: resource_len %llu\n", ESIF_FUNC, resource_len);
err = pci_request_regions(dev_ptr, DRIVER_NAME);
if (err) {
ESIF_TRACE_ERROR("%s: failed to request pci region\n",
ESIF_FUNC);
goto error_cleanup;
}
ESIF_TRACE_DEBUG("%s: have pci region\n", ESIF_FUNC);
pi.mem_size = resource_len;
pi.mem_base = ioremap_nocache(resource_start, resource_len);
if (!pi.mem_base) {
err = -ENOMEM;
ESIF_TRACE_ERROR("%s: failed to map iomem\n", ESIF_FUNC);
goto error_cleanup;
}
ESIF_TRACE_DEBUG("%s: mem_base %p\n", ESIF_FUNC, pi.mem_base);
{
u8 *class_ptr = (u8 *)&dev_ptr->class;
pi.pci_vendor = dev_ptr->vendor;
pi.pci_device = dev_ptr->device;
pi.pci_revision = dev_ptr->revision;
pi.pci_class = *(class_ptr + 2);
pi.pci_sub_class = *(class_ptr + 1);
pi.pci_prog_if = *class_ptr;
}
switch (dev_ptr->device) {
default:
ESIF_TRACE_DEBUG("%s: %s pch thermal device detected\n",
ESIF_FUNC, esif_device_str(dev_ptr->device));
break;
}
/* Try To Map ACPI Handle For This PCI Device */
pi.acpi_handle = DEVICE_ACPI_HANDLE(&dev_ptr->dev);
if (pi.acpi_handle) {
struct acpi_buffer acpi_scope = {
.length = ACPI_ALLOCATE_BUFFER};
acpi_status status = acpi_get_name(pi.acpi_handle,
ACPI_FULL_PATHNAME,
&acpi_scope);
ESIF_TRACE_DEBUG("%s: have acpi handle %p\n",
ESIF_FUNC,
pi.acpi_handle);
if (ACPI_FAILURE(status)) {
ESIF_TRACE_DEBUG("%s: acpi_get_name error %d\n",
ESIF_FUNC,
status);
} else {
strncpy(pi.acpi_scope,
acpi_scope.pointer,
ESIF_SCOPE_LEN);
ESIF_TRACE_DEBUG("%s: name = %s\n",
ESIF_FUNC,
pi.acpi_scope);
kfree(acpi_scope.pointer);
}
status = acpi_install_notify_handler(pi.acpi_handle,
ACPI_ALL_NOTIFY, acpi_notify, &pi);
if (ACPI_FAILURE(status))
ESIF_TRACE_DEBUG("%s: acpi_install_notify_handler error %d\n",
ESIF_FUNC, status);
}
rc = esif_lf_register_participant(&pi);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
error_cleanup:
if (enabled)
pci_disable_device(dev_ptr);
return err;
}
/* Remove */
static void pci_pch_remove(struct pci_dev *dev_ptr)
{
enum esif_rc rc;
if (pi.acpi_handle)
acpi_remove_notify_handler(pi.acpi_handle, ACPI_ALL_NOTIFY,
acpi_notify);
rc = esif_lf_unregister_participant(&pi);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
iounmap(pi.mem_base);
pci_release_region(dev_ptr, 0);
}
/* Shutdonw */
static void pci_pch_shutdown(struct pci_dev *dev_ptr)
{
enum esif_rc rc;
rc = pch_send_event(ESIF_EVENT_PARTICIPANT_SHUTDOWN, 'NA', NULL);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
}
/* Suspend */
static int pci_pch_suspend(
struct pci_dev *dev_ptr,
pm_message_t state
)
{
enum esif_rc rc;
rc = pch_send_event(ESIF_EVENT_PARTICIPANT_SUSPEND, 'NA', &state);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Resume */
static int pci_pch_resume(struct pci_dev *dev_ptr)
{
enum esif_rc rc = pch_send_event(ESIF_EVENT_PARTICIPANT_RESUME,
'NA',
NULL);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* PCI Driver */
static struct pci_driver pci_pch_driver = {
.name = DRIVER_NAME,
.id_table = esif_pci_pch_ids,
.probe = pci_pch_probe,
.remove = pci_pch_remove,
.shutdown = pci_pch_shutdown,
.suspend = pci_pch_suspend,
.resume = pci_pch_resume
};
#else /* ESIF_ATTR_PLATFORM */
/*
** Platform Bus Driver
*/
/* Probe */
static int platform_pch_probe(struct platform_device *dev_ptr)
{
enum esif_rc rc = ESIF_OK;
char *kobj_path_ptr = NULL;
ESIF_TRACE_DEBUG("%s: dev %p\n", ESIF_FUNC, dev_ptr);
/* Grab Linux Device Driver Not Platform Driver */
pi.device = &dev_ptr->dev;
snprintf(pi.driver_name, ESIF_NAME_LEN, "%s.ko", DRIVER_NAME);
snprintf(pi.device_name, ESIF_NAME_LEN, "%s", dev_name(&dev_ptr->dev));
kobj_path_ptr = kobject_get_path(&dev_ptr->dev.kobj, GFP_ATOMIC);
if (NULL != kobj_path_ptr) {
snprintf(pi.device_path, ESIF_PATH_LEN, "%s", kobj_path_ptr);
kfree(kobj_path_ptr);
}
rc = esif_lf_register_participant(&pi);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Remove */
static int platform_pch_remove(struct platform_device *dev_ptr)
{
enum esif_rc rc;
rc = esif_lf_unregister_participant(&pi);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Shutdown */
static void platform_pch_shutdown(struct platform_device *dev_ptr)
{
enum esif_rc rc;
rc = pch_send_event(ESIF_EVENT_PARTICIPANT_RESUME, 'NA', NULL);
ESIF_TRACE_DEBUG("%s dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
}
/* Suspend */
static int platform_pch_suspend(
struct platform_device *dev_ptr,
pm_message_t state
)
{
enum esif_rc rc;
rc = pch_send_event(ESIF_EVENT_PARTICIPANT_SUSPEND, 'NA', &state);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Resume */
static int platform_pch_resume(struct platform_device *dev_ptr)
{
enum esif_rc rc;
rc = pch_send_event(ESIF_EVENT_PARTICIPANT_RESUME, 'NA', NULL);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Platform Driver */
static struct platform_driver platform_pch_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
.probe = platform_pch_probe,
.remove = platform_pch_remove,
.shutdown = platform_pch_shutdown,
.suspend = platform_pch_suspend,
.resume = platform_pch_resume
};
static struct platform_device *g_pd_ptr;
#endif
/* Load */
static int __init dptf_pch_load(void)
{
int rc = 0;
ESIF_TRACE_INFO("%s: %s\n", ESIF_FUNC, ESIF_PARTICIPANT_PCH_DESC);
ESIF_TRACE_INFO("%s: %s\n", ESIF_FUNC, ESIF_COPYRIGHT);
#ifndef ESIF_ATTR_PLATFORM
rc = pci_register_driver(&pci_pch_driver);
#else /* ESIF_ATTR_PLATFORM */
ESIF_TRACE_INFO("%s: %s\n", ESIF_FUNC, ESIF_PLATFORM_MSG);
rc = platform_driver_register(&platform_pch_driver);
/* Simulate Device Insert */
g_pd_ptr = platform_device_register_simple(DRIVER_NAME, 0, NULL, 0);
if (NULL == g_pd_ptr)
rc = -ENOMEM;
#endif
return rc;
}
/* Unload */
static void __exit dptf_pch_unload(void)
{
#ifndef ESIF_ATTR_PLATFORM
pci_unregister_driver(&pci_pch_driver);
#else /* ESIF_ATTR_PLATFORM */
/* Simulate Device Removal */
if (NULL != g_pd_ptr)
platform_device_unregister(g_pd_ptr);
platform_driver_unregister(&platform_pch_driver);
#endif
}
/*
******************************************************************************
* PUBLIC
******************************************************************************
*/
/* Module Entry / Exit */
module_init(dptf_pch_load);
module_exit(dptf_pch_unload);
MODULE_VERSION(ESIF_VERSION);
MODULE_DESCRIPTION(ESIF_PARTICIPANT_PCH_DESC);
MODULE_LICENSE(ESIF_LICENSE);
MODULE_AUTHOR(ESIF_AUTHOR);
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,294 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#define ESIF_ATTR_OS_LINUX_DRIVER
#define ESIF_DEBUG_MODULE ESIF_DEBUG_MOD_LINUX
#define DRIVER_NAME "dptf_plat"
#include "esif_lf.h"
/* Event Receive */
static enum esif_rc plat_recv_event(
enum esif_event_type type,
u16 domain,
struct esif_data *data_ptr
)
{
ESIF_TRACE_DEBUG("%s: event received domain %d type %d\n",
ESIF_FUNC,
domain,
type);
return ESIF_OK;
}
/* ESIF Particpant INTERFACE */
static struct esif_participant_iface pi = {
.version = ESIF_PARTICIPANT_VERSION,
.class_guid = ESIF_PARTICIPANT_PLAT_CLASS_GUID,
.enumerator = ESIF_PARTICIPANT_ENUM_PLAT,
.flags = 0x0,
.name = ESIF_PARTICIPANT_PLAT_NAME,
.desc = ESIF_PARTICIPANT_PLAT_DESC,
.driver_name = "?", /* Filled In Dynamically By Driver */
.device_name = "?", /* Filled In Dynamically By Driver */
.device_path = "NA", /* Filled In Dynamically By Driver */
.device = NULL, /* Driver Assigned */
.mem_base = NULL, /* Driver Assigned */
.mem_size = 0, /* Driver Assigned */
.acpi_handle = NULL, /* Driver Assigned */
/* EVENT */
.recv_event = plat_recv_event,
.send_event = NULL, /* Filled In Dynamically By esif_lf */
/* ACPI */
.acpi_device = "*", /* Don't Care */
.acpi_scope = "*", /* Don't Care */
.acpi_uid = ESIF_PARTICIPANT_INVALID_UID, /* Don't Care */
.acpi_type = ESIF_PARTICIPANT_INVALID_TYPE, /* Don't Care */
/* PCI */
.pci_vendor = 0, /* Not Used */
.pci_device = 0, /* Not Used */
.pci_bus = 0, /* Not Used */
.pci_bus_device = 0, /* Not Used */
.pci_function = 0, /* Not Used */
.pci_revision = 0, /* Not Used */
.pci_class = 0, /* Not Used */
.pci_sub_class = 0, /* Not Used */
.pci_prog_if = 0, /* Not Used */
};
/*
******************************************************************************
* LINUX Driver Code Below Here. Implemetned As Platform Driver For
* Prototype to avoid the need for a CRB.
******************************************************************************
*/
/*
******************************************************************************
* PRIVATE
******************************************************************************
*/
/* Event Send */
static enum esif_rc acpi_send_event(
enum esif_event_type type,
u16 domain,
void *data_ptr
)
{
if (NULL == pi.send_event)
return ESIF_E_CALLBACK_IS_NULL;
return pi.send_event(&pi, type, domain, data_ptr);
}
/* Probe */
static int platform_plat_probe(struct platform_device *dev_ptr)
{
enum esif_rc rc = ESIF_OK;
char *kobj_path_ptr = NULL;
ESIF_TRACE_DEBUG("%s: dev %p\n", ESIF_FUNC, dev_ptr);
/* Grab Linux Device Driver Not Platform Driver */
pi.device = &dev_ptr->dev;
snprintf(pi.driver_name, ESIF_NAME_LEN, "%s.ko", DRIVER_NAME);
snprintf(pi.device_name,
ESIF_NAME_LEN,
"%s.%d",
dev_ptr->name,
dev_ptr->id);
kobj_path_ptr = kobject_get_path(&dev_ptr->dev.kobj, GFP_ATOMIC);
if (NULL != kobj_path_ptr) {
snprintf(pi.device_path, ESIF_PATH_LEN, "%s", kobj_path_ptr);
kfree(kobj_path_ptr);
}
rc = esif_lf_register_participant(&pi);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Remove */
static int platform_plat_remove(struct platform_device *dev_ptr)
{
enum esif_rc rc;
rc = esif_lf_unregister_participant(&pi);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Shutdown */
static void platform_plat_shutdown(struct platform_device *dev_ptr)
{
enum esif_rc rc;
rc = acpi_send_event(ESIF_EVENT_PARTICIPANT_SHUTDOWN, 'NA', NULL);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
}
/* Suspend */
static int platform_plat_suspend(
struct platform_device *dev_ptr,
pm_message_t state
)
{
enum esif_rc rc;
rc = acpi_send_event(ESIF_EVENT_PARTICIPANT_SUSPEND, 'NA', &state);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Resume */
static int platform_plat_resume(struct platform_device *dev_ptr)
{
enum esif_rc rc;
rc = acpi_send_event(ESIF_EVENT_PARTICIPANT_RESUME, 'NA', NULL);
ESIF_TRACE_DEBUG("%s: dev %p rc = %d\n", ESIF_FUNC, dev_ptr, rc);
if (ESIF_OK != rc)
return -EINVAL;
return 0;
}
/* Platform Driver */
static struct platform_driver platform_plat_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
.probe = platform_plat_probe,
.remove = platform_plat_remove,
.shutdown = platform_plat_shutdown,
.suspend = platform_plat_suspend,
.resume = platform_plat_resume
};
/* Platform Device */
static struct platform_device *g_pd_ptr;
/* Load */
static int __init dptf_plat_load(void)
{
ESIF_TRACE_INFO("%s: %s\n", ESIF_FUNC, ESIF_PARTICIPANT_PLAT_DESC);
ESIF_TRACE_INFO("%s: %s\n", ESIF_FUNC, ESIF_COPYRIGHT);
ESIF_TRACE_INFO("%s: %s\n", ESIF_FUNC, ESIF_PLATFORM_MSG);
platform_driver_register(&platform_plat_driver);
/* Simulate Device Insert */
/* platform_device_register(&platform_plat_device); */
g_pd_ptr = platform_device_register_simple(DRIVER_NAME, 0, NULL, 0);
if (NULL == g_pd_ptr)
return -ENOMEM;
return 0;
}
/* Unload */
static void __exit dptf_plat_unload(void)
{
/* Simulate Device Removal */
if (NULL != g_pd_ptr)
platform_device_unregister(g_pd_ptr);
platform_driver_unregister(&platform_plat_driver);
}
/*
******************************************************************************
* PUBLIC
******************************************************************************
*/
/* Module Entry / Exit */
module_init(dptf_plat_load);
module_exit(dptf_plat_unload);
MODULE_VERSION(ESIF_VERSION);
MODULE_DESCRIPTION(ESIF_PARTICIPANT_PLAT_DESC);
MODULE_LICENSE(ESIF_LICENSE);
MODULE_AUTHOR(ESIF_AUTHOR);
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,306 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_H_
#define _ESIF_H_
#define ESIF_ATTR_WEBSOCKET
typedef char *esif_string; /* Opaque ESIF String ASCIIZ Today */
/* Linux Derrived OS */
#if defined(ESIF_ATTR_OS_LINUX) || \
defined(ESIF_ATTR_OS_ANDROID) || \
defined(ESIF_ATTR_OS_CHROME)
#define ESIF_CALLCONV
#define ESIF_ATTR_OS "linux" /* OS Is Linux */
/*
* ESIF_FEAT_OPT_SYSFS exports SYSFS entries. It is defined
* in ESIF_LF/Linuxx64/Debug/makefile and
* ESIF_LF/Linuxx64/Release/makefile. It is disabled by default.
* To enable it, it must be uncommented out in makefile.
*/
#define ESIF_INLINE inline /* Normalize Compiler */
#define ESIF_FUNC __func__ /* Normalize Compiler */
#define ESIF_PATH_SEP "/" /* Path Seperator */
#ifdef __cpluscplus
#define ESIF_ELEMENT(x) x = /* Support C99 Init */
#else /* __cpluscplus */
#define ESIF_ELEMENT(x) /* Emulate/Ignore C99 Init */
#endif /* __cplusplus */
/* Deduce Platform based on predefined gcc compiler flags */
#ifdef __x86_64__
#define ESIF_ATTR_64BIT
#endif /* __x86_64__ */
#endif /* Linux Derrived OS */
/* Android Override For Linux */
#ifdef ESIF_ATTR_OS_ANDROID
#undef ESIF_ATTR_OS
#define ESIF_ATTR_OS "android"
#define ESIF_ATTR_OS_LINUX
#endif /* ESIF_ATTR_OS_ANDROID */
/* Chrome Override For Linux */
#ifdef ESIF_ATTR_OS_CHROME
#undef ESIF_ATTR_OS
#define ESIF_ATTR_OS "chrome"
#define ESIF_ATTR_OS_LINUX
#endif /* ESIF_ATTR_OS_CHROME */
#ifdef ESIF_ATTR_OS_WINDOWS
#define ESIF_CALLCONV __cdecl
#define ESIF_ATTR_OS "windows" /* OS Is Windows */
#define ESIF_INLINE __inline /* Normalize Compiler */
#define ESIF_FUNC __FUNCTION__ /* Normalize Compiler */
#define ESIF_PATH_SEP "\\" /* Path Seperator */
#define ESIF_ELEMENT(x) /* Emulate/Ignore C99 Init */
/* Note Static Init Must Be */
/* In Structure Order */
/* Build option to enable coalescable timers in Windows */
#define ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS
/* We Use The Linux Dictionary So Add For Windows */
typedef unsigned char u8; /* A BYTE */
typedef unsigned short u16; /* A WORD */
typedef unsigned int u32; /* A DWORD */
typedef unsigned long long u64; /* A QWORD */
/* Deduce Platform based on predefined compiler flags */
#ifdef _WIN64
#define ESIF_ATTR_64BIT
#endif /* _WIN64 */
/* Override windows DEBUG To ESIF or Project can include ESIF_ATTR_DEBUG */
#ifdef _DEBUG
#define ESIF_ATTR_DEBUG
#endif /* _DEBUG */
#endif /* ESIF_ATTR_OS_WINDOWS */
#ifdef ESIF_ATTR_KERNEL
#include "esif_version.h"
#ifdef ESIF_ATTR_OS_LINUX
#include <linux/module.h> /* Linux Module */
#include <linux/platform_device.h> /* Linux Platform Device */
#include <linux/acpi.h> /* Linux ACPI Device */
#include <linux/pci.h> /* Linux PCI Device */
#include <linux/thermal.h> /* Linux Thermals */
#include <linux/kobject.h> /* Linux Kernel Objects */
#include <linux/version.h> /* Linux Kernel Version */
/*
* Devices Are Defined To Be Opaque to allow for OS
* implementation of Pointer VS Handle Etc. Linux uses a
* a device pointer.
*/
typedef struct device *esif_device_t;
#define UNREFERENCED_PARAMETER(x)
#endif /* ESIF_ATTR_KERNEL::ESIF_ATTR_OS_LINUX */
#ifdef ESIF_ATTR_OS_WINDOWS
#include "ntddk.h" /* The Windows DDK */
#include "wdf.h" /* Windows Driver Framework */
#include "INITGUID.H" /* Init GUID */
#include "wdmguid.h" /* Windows GUIDS */
/*
** Suppress Windows Warnings for warn level 4. Need to find out if we can
** challenge the Windows Blue /W4 /WX with no pragramas assumption?
*/
#pragma warning(disable : 4127) /* Conditional expression is constant */
#pragma warning(disable : 4204) /* Non-constant aggregate initializer */
#pragma warning(disable : 4221) /* Can't be initialized using address of
automatic variable */
/*
* Devices Are Defined To Be Opaque to allow for OS
* implementation of Pointer VS Handle Etc. Windows uses a
* a device handle for WDF.
*/
typedef WDFDEVICE esif_device_t;
extern WDFDEVICE g_wdf_device_handle;
extern WDFQUEUE g_wdf_ipc_queue_handle;
/* Map Linux To Windows */
#define __iomem /* NOOP For Windows */
#define __le16 short int /* Add To Windows Dictionary */
#endif /* ESIF_ATTR_KERNEL:: ESIF_ATTR_OS_WINDOWS */
#endif /* ESIF_ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
/*
* OS Agnostic
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
/* Linux */
#ifdef ESIF_ATTR_OS_LINUX
#include <sys/ioctl.h> /* IOCTL Interface */
#include <unistd.h> /* Unix Standard Library */
#include <sys/time.h> /* Time */
#define ESIF_ASSERT(x) (0) /* NOOP For Now */
#define UNREFERENCED_PARAMETER(x) (0) /* NOOP For Now */
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
#endif /* USER::ESIF_ATTR_OS_LINUX */
#ifdef ESIF_ATTR_OS_WINDOWS
#define _WINSOCKAPI_ /* Override for Winsock */
#include <windows.h> /* Windows Includes Almost Everything */
#include <winioctl.h> /* Except IOCTL Interface */
#define ESIF_ASSERT(x) (0) /* NOOP For Now */
#pragma warning(disable : 4204) /* Non-constant aggregate initializer */
#pragma warning(disable : 4221) /* Can't be init'd with addr of autos */
#endif /* USER::ESIF_ATTR_OS_WINDOWS */
typedef u8 UInt8; /* A CCB BYTE */
typedef char Int8;
typedef u16 UInt16; /* A CCB WORD */
typedef short Int16;
typedef u32 UInt32; /* A CCB DWORD */
typedef int Int32;
typedef u64 UInt64; /* A CCB QWORD */
typedef long long Int64;
typedef u8 Bool; /* BOOLEAN */
typedef esif_string EsifString;
#endif /* ESIF_ATTR_USER */
/* ID Lookup Failed To Find String */
#define ESIF_NOT_AVAILABLE "NA"
/* Data Lengths */
#define ESIF_NAME_LEN 64 /* Maximum Name Length */
#define ESIF_DESC_LEN 64 /* Maximum Description Length */
#define ESIF_SCOPE_LEN 64 /* Maximum ACPI Scope Length */
#define ESIF_OBJ_LEN 64 /* Maximum Object Name Length */
#define ESIF_GUID_LEN 16 /* Length of a GUID In Bytes */
#define ESIF_PATH_LEN 128 /* Maximum Path Length */
#define ESIF_LIBPATH_LEN 128 /* Maximum Lib Path Length */
#define ESIF_ACPI_UID_LEN 64 /* Maximum ACPI UID Length */
#define ESIF_TRUE 1 /* C True */
#define ESIF_FALSE 0 /* C False */
#define ESIF_PERCENT_CONV_FACTOR 100 /* Percentages are in 100ths */
#ifdef ESIF_ATTR_OS_WINDOWS
typedef HANDLE esif_handle_t;
#define ESIF_INVALID_HANDLE INVALID_HANDLE_VALUE
#endif /* ESIF_ATTR_OS_WINDOWS */
#ifdef ESIF_ATTR_OS_LINUX
typedef int esif_handle_t;
#define ESIF_INVALID_HANDLE (-1)
#endif /* ESIF_ATTR_OS_LINUX */
typedef u32 esif_flags_t; /* FLAGS */
typedef u8 esif_guid_t[ESIF_GUID_LEN]; /* GUID */
typedef u8 esif_ver_t; /* Version */
typedef u32 esif_temp_t; /* Temperature */
typedef u32 esif_power_t; /* Power */
#define ESIF_PLATFORM_MSG "Platform Driver Intended For Internal VM Use Only"
#define ESIF_LICENSE "GPL"
#define ESIF_AUTHOR "brad.geltz@intel.com,brian.bian@intel.com"
#ifdef ESIF_ATTR_64BIT
#define ESIF_PLATFORM_TYPE "x64"
#else
#define ESIF_PLATFORM_TYPE "x86"
#endif /* ESIF_ATTR_64BIT */
#ifdef ESIF_ATTR_DEBUG
#define ESIF_BUILD_TYPE "Debug"
#else
#define ESIF_BUILD_TYPE "Release"
#endif /* ESIF_ATTR_DEBUG */
#include "esif_debug.h" /* Debug Helpers */
#include "esif_rc.h" /* Return Codes */
#include "esif_mempool.h" /* Memory Pool */
#include "esif_ccb.h" /* Common Code Base */
#include "esif_memtype.h" /* Memory Types */
#ifdef ESIF_ATTR_KERNEL
extern esif_ccb_lock_t g_mempool_lock;
#endif /* ESIF_ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
#include "esif_data.h"
/* Include All Headers Here */
#include "esif_uf.h"
#include "esif_uf_iface.h"
#include "esif_uf_app_iface.h"
#include "esif_uf_esif_iface.h"
#endif /* ESIF_ATTR_USER */
#endif /* _ESIF_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,208 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_ACTION_H_
#define _ESIF_ACTION_H_
#ifdef ESIF_ATTR_KERNEL
/* include enum esif_action_type, and lookup */
#include "esif.h"
/* Action */
struct esif_lp_action {
enum esif_action_type type; /* Execution Method For This Primitive
* */
u32 *p1_ptr; /* Parameter 1 */
u32 *p2_ptr; /* Parameter 2 */
u32 *p3_ptr; /* Parameter 3 */
u32 *p4_ptr; /* Parameter 4 */
u32 *p5_ptr; /* Parameter 5 */
enum esif_action_type (*get_type)(const struct esif_lp_action *
action_ptr);
u32 (*get_p1_u32)(const struct esif_lp_action *action_ptr);
u32 (*get_p2_u32)(const struct esif_lp_action *action_ptr);
u32 (*get_p3_u32)(const struct esif_lp_action *action_ptr);
u32 (*get_p4_u32)(const struct esif_lp_action *action_ptr);
u32 (*get_p5_u32)(const struct esif_lp_action *action_ptr);
};
/* Forward Decleration */
struct esif_lp_primitive;
struct esif_lp;
enum esif_rc esif_execute_action(struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_lp *lp_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr);
/* ACPI */
enum esif_rc esif_action_acpi_init(void);
void esif_action_acpi_exit(void);
enum esif_rc esif_get_action_acpi(acpi_handle acpi_handle,
const u32 acpi_method,
const struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr);
enum esif_rc esif_set_action_acpi(acpi_handle acpi_handle,
const u32 acpi_method,
struct esif_data *req_data_ptr);
/* CONSTANT */
enum esif_rc esif_action_const_init(void);
void esif_action_const_exit(void);
enum esif_rc esif_get_action_const(const u32 value,
const struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr);
/* CODE */
struct esif_primitive_tuple;
enum esif_rc esif_action_code_init(void);
void esif_action_code_exit(void);
enum esif_rc esif_get_action_code(struct esif_lp *lp_ptr,
const struct esif_primitive_tuple *tuple_ptr,
const struct esif_lp_action *action_ptr,
const struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr);
enum esif_rc esif_set_action_code(struct esif_lp *lp_ptr,
const struct esif_primitive_tuple *tuple_ptr,
const struct esif_lp_action *action_ptr,
const struct esif_data *req_data_ptr);
/* MBI */
enum esif_rc esif_action_mbi_init(void);
void esif_action_mbi_exit(void);
enum esif_rc esif_get_action_mbi(const u8 port,
const u8 reg,
const u8 bit_start,
const u8 bit_stop,
const struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr);
enum esif_rc esif_set_action_mbi(const u8 port,
const u8 reg,
const u8 bit_start,
const u8 bit_stop,
const struct esif_data *req_data_ptr);
/* MMIO */
enum esif_rc esif_action_mmio_init(void);
void esif_action_mmio_exit(void);
enum esif_rc esif_get_action_mmio(const void __iomem *base_addr,
const u32 offset,
const u8 bit_start,
const u8 bit_stop,
const struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr);
enum esif_rc esif_set_action_mmio(const void __iomem *base_addr,
const u32 offset,
const u8 bit_start,
const u8 bit_stop,
const struct esif_data *req_data_ptr);
/* MSR */
enum esif_rc esif_action_msr_init(void);
void esif_action_msr_exit(void);
enum esif_rc esif_get_action_msr(const u32 msr,
const u8 bit_start,
const u8 bit_stop,
const u32 cpus,
const u32 hint,
const struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr);
enum esif_rc esif_set_action_msr(const u32 msr,
const u8 bit_start,
const u8 bit_stop,
const u32 cpus,
const u32 hint,
const struct esif_data *req_data_ptr);
/* VAR */
enum esif_rc esif_action_var_init(void);
void esif_action_var_exit(void);
enum esif_rc esif_get_action_var(const struct esif_data *var,
const struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr);
enum esif_rc esif_set_action_var(struct esif_data *var,
const struct esif_data *req_data_ptr);
/* SYSTEM IO */
enum esif_rc esif_action_systemio_init(void);
void esif_action_systemio_exit(void);
enum esif_rc esif_get_action_systemio(const struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr);
enum esif_rc esif_set_action_systemio(const struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr);
#endif /* ESIF_ACTION_KERNEL */
#endif /* _ESIF_ACTION_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,119 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_CCB_H_
#define _ESIF_CCB_H_
#ifdef ESIF_ATTR_USER
#include "esif.h"
#endif
/* Debug Options */
#define MEMORY_DEBUG NO_ESIF_DEBUG
#define MEMPOOL_DEBUG NO_ESIF_DEBUG
#define MEMTYPE_DEBUG NO_ESIF_DEBUG
#define TIMER_DEBUG NO_ESIF_DEBUG
#define THREAD_DEBUG NO_ESIF_DEBUG
#ifdef ESIF_ATTR_USER
#include <stdlib.h> /* Standard Library */
#include <string.h> /* String Library */
#ifdef ESIF_ATTR_OS_LINUX
#define esif_ccb_sleep sleep /* Sleep Wrapper */
#define esif_ccb_sleep_msec(x) usleep(x * 1000);
#define esif_ccb_stat stat /* Stat Wrapper */
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
#include <time.h> /* Time Library */
#include <winsock2.h> /* Timeval Struct Def */
#define esif_ccb_sleep(x) Sleep(x * 1000)
#define esif_ccb_sleep_msec Sleep
#define esif_ccb_stat(a, b) _stat(a, (struct _stat *)b)
#endif
#include "esif_uf_ccb_thread.h"
#include "esif_uf_ccb_library.h"
#endif /* ESIF_ATTR_USER */
#include "esif_ccb_memory.h"
#include "esif_ccb_lock.h"
#include "esif_ccb_time.h"
#include "esif_ccb_string.h"
#include "esif_ccb_mempool.h"
#include "esif_ccb_sem.h"
#include "esif_ccb_timer.h"
#ifdef ESIF_ATTR_USER
#include "esif_uf_ccb_file.h"
#endif
#ifdef ESIF_ATTR_KERNEL
#include "esif_lf_ccb_mbi.h"
#include "esif_lf_ccb_mmio.h"
#include "esif_lf_ccb_msr.h"
#include "esif_lf_ccb_acpi.h"
#endif /* ESIF_ATTR_KERNEL */
#endif /* _ESIF_CCB_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,200 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ATOMIC_LIB_H
#define _ATOMIC_LIB_H
/*
** C/C++ OS Agnostic Implementation of atomic integer operations.
**
** Interface is based on native Linux atomic_t kernel type (atomic.h)
** Note that atomic_t size varies depending on mode, platform, and OS:
**
** Platform Mode size Implementation
** ------------ ------- ------- ----------------------------------------------
** Linux x86 Kernel 32-bit atomic_t native type
** Linux x86 User 32-bit __sync* builtins
** Linux x64 Kernel 64-bit atomic_t native type
** Linux x64 User 64-bit __sync* builtins
** Windows x86 Kernel 32-bit _Interlocked* intrinsic functions
** Windows x86 User 32-bit _Interlocked* intrinsic functions
** Windows x64 Kernel 64-bit _Interlocked*64 intrinsic functions
** Windows x64 User 64-bit _Interlocked*64 intrinsic functions
*/
#ifdef ESIF_ATTR_KERNEL
/* Kernel mode always uses native x86/x64 type */
#ifdef ESIF_ATTR_OS_WINDOWS
/* Windows */
# include <wdm.h>
# ifdef ESIF_ATTR_64BIT
typedef LONGLONG atomic_t;
typedef LONGLONG _atomic_int;
# define ATOMIC_INIT(i) (i)
# define ATOMIC_FMT "%lld"
# pragma intrinsic(_InterlockedExchange64)
# pragma intrinsic(_InterlockedIncrement64)
# pragma intrinsic(_InterlockedDecrement64)
# pragma intrinsic(_InterlockedExchangeAdd64)
# define atomic_read(v) _InterlockedExchangeAdd64(v, 0)
# define atomic_set(v, i) _InterlockedExchange64(v, i)
# define atomic_inc(v) _InterlockedIncrement64(v)
# define atomic_dec(v) _InterlockedDecrement64(v)
# define atomic_add(i, v) _InterlockedExchangeAdd64(v, i)
# define atomic_sub(i, v) _InterlockedExchangeAdd64(v, -(i))
# else
typedef LONG atomic_t;
typedef LONG _atomic_int;
# define ATOMIC_INIT(i) (i)
# define ATOMIC_FMT "%ld"
# pragma intrinsic(_InterlockedExchange)
# pragma intrinsic(_InterlockedIncrement)
# pragma intrinsic(_InterlockedDecrement)
# pragma intrinsic(_InterlockedExchangeAdd)
# define atomic_read(v) _InterlockedExchangeAdd(v, 0)
# define atomic_set(v, i) _InterlockedExchange(v, i)
# define atomic_inc(v) _InterlockedIncrement(v)
# define atomic_dec(v) _InterlockedDecrement(v)
# define atomic_add(i, v) _InterlockedExchangeAdd(v, i)
# define atomic_sub(i, v) _InterlockedExchangeAdd(v, -(i))
# endif
#endif
#ifdef ESIF_ATTR_OS_LINUX
/* Linux */
# include <asm/atomic.h> /* native atomic_t typedef here */
typedef long _atomic_int;
# define ATOMIC_FMT "%ld"
#endif
#endif
#ifdef ESIF_ATTR_USER
#ifdef ESIF_ATTR_OS_WINDOWS
# ifdef ESIF_ATTR_64BIT
typedef LONGLONG _atomic_int;
# define ATOMIC_FMT "%lld"
# else
typedef LONG _atomic_int;
# define ATOMIC_FMT "%ld"
# endif
#else
typedef long _atomic_int;
# define ATOMIC_FMT "%ld"
#endif
/* Disable User-Mode Atomic operations. Use at your own risk */
#if defined(ATOMIC_LIB_DISABLE)
typedef volatile _atomic_int atomic_t;
# define ATOMIC_INIT(i) (i)
# define atomic_read(v) (*(v))
# define atomic_set(v, i) (*(v) = (i))
# define atomic_inc(v) ((*(v))++)
# define atomic_dec(v) ((*(v))--)
# define atomic_add(i, v) (*(v) += (i))
# define atomic_sub(i, v) (*(v) -= (i))
#elif defined(ESIF_ATTR_OS_WINDOWS)
/* Windows: Use Interlocked intrinsic functions */
typedef volatile _atomic_int atomic_t;
#define ATOMIC_INIT(i) (i)
#include <intrin.h>
#ifdef ESIF_ATTR_64BIT
# pragma intrinsic(_InterlockedExchange64)
# pragma intrinsic(_InterlockedIncrement64)
# pragma intrinsic(_InterlockedDecrement64)
# pragma intrinsic(_InterlockedExchangeAdd64)
# define atomic_read(v) _InterlockedExchangeAdd64(v, 0)
# define atomic_set(v, i) _InterlockedExchange64(v, i)
# define atomic_inc(v) _InterlockedIncrement64(v)
# define atomic_dec(v) _InterlockedDecrement64(v)
# define atomic_add(i, v) _InterlockedExchangeAdd64(v, i)
# define atomic_sub(i, v) _InterlockedExchangeAdd64(v, -(i))
#else
# pragma intrinsic(_InterlockedExchange)
# pragma intrinsic(_InterlockedIncrement)
# pragma intrinsic(_InterlockedDecrement)
# pragma intrinsic(_InterlockedExchangeAdd)
# define atomic_read(v) _InterlockedExchangeAdd(v, 0)
# define atomic_set(v, i) _InterlockedExchange(v, i)
# define atomic_inc(v) _InterlockedIncrement(v)
# define atomic_dec(v) _InterlockedDecrement(v)
# define atomic_add(i, v) _InterlockedExchangeAdd(v, i)
# define atomic_sub(i, v) _InterlockedExchangeAdd(v, -(i))
#endif
#else
/* Linux: Use __sync builtin functions (Requires gcc 4.4 or higher) */
typedef volatile _atomic_int atomic_t;
#define ATOMIC_INIT(i) (i)
#define atomic_read(v) __sync_add_and_fetch(v, 0)
#define atomic_set(v, i) __sync_lock_test_and_set(v, i)
#define atomic_inc(v) __sync_add_and_fetch(v, 1)
#define atomic_dec(v) __sync_sub_and_fetch(v, 1)
#define atomic_add(i, v) __sync_add_and_fetch(v, i)
#define atomic_sub(i, v) __sync_sub_and_fetch(v, i)
#endif /* Linux */
#endif /* ESIF_ATTR_USER */
#endif /* _ATOMIC_LIB_H */

View File

@@ -0,0 +1,319 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_CCB_LOCK_H_
#define _ESIF_CCB_LOCK_H_
/******************************************************************************
* KERNEL LOCKS
******************************************************************************/
#ifdef ESIF_ATTR_KERNEL
/* Use Shareable Read/Write Locks */
#ifdef ESIF_ATTR_OS_LINUX
typedef rwlock_t esif_ccb_lock_t;
typedef struct rw_semaphore esif_ccb_low_priority_thread_lock_t;
#define esif_ccb_lock_init(lockPtr) rwlock_init(lockPtr)
#define esif_ccb_lock_uninit(lockPtr) /* not used */
#define esif_ccb_write_lock(lockPtr) write_lock(lockPtr)
#define esif_ccb_write_unlock(lockPtr) write_unlock(lockPtr)
#define esif_ccb_read_lock(lockPtr) read_lock(lockPtr)
#define esif_ccb_read_unlock(lockPtr) read_unlock(lockPtr)
#define esif_ccb_low_priority_thread_lock_init(lockPtr) init_rwsem(lockPtr)
#define esif_ccb_low_priority_thread_lock_uninit(lockPtr) /* not used */
#define esif_ccb_low_priority_thread_write_lock(lockPtr) down_write(lockPtr)
#define esif_ccb_low_priority_thread_write_unlock(lockPtr) up_write(lockPtr)
#define esif_ccb_low_priority_thread_read_lock(lockPtr) down_read(lockPtr)
#define esif_ccb_low_priority_thread_read_unlock(lockPtr) up_read(lockPtr)
#endif /* ESIF_ATTR_OS_LINUX */
#ifdef ESIF_ATTR_OS_WINDOWS
typedef struct esif_ccb_lock {
WDFSPINLOCK lock; /* Spin Lock */
} esif_ccb_lock_t;
typedef struct esif_ccb_low_priority_thread_lock {
WDFWAITLOCK lock; /* Wait Lock */
} esif_ccb_low_priority_thread_lock_t;
static ESIF_INLINE void esif_ccb_lock_init (esif_ccb_lock_t *lockPtr)
{
/* TODO: Change creation functions to return status and check in code */
NTSTATUS stat;
stat = WdfSpinLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &lockPtr->lock);
NT_SUCCESS(stat);
}
#define esif_ccb_lock_uninit(lockPtr) /* not used */
_IRQL_raises_(DISPATCH_LEVEL)
_IRQL_saves_global_(OldIrql, lockPtr->lock)
_Requires_lock_not_held_(lockPtr->lock)
_Acquires_lock_(lockPtr->lock)
static ESIF_INLINE void esif_ccb_write_lock (esif_ccb_lock_t *lockPtr)
{WdfSpinLockAcquire(lockPtr->lock);}
_IRQL_restores_global_(OldIrql, lockPtr->lock)
_IRQL_requires_(DISPATCH_LEVEL)
_Requires_lock_held_(lockPtr->lock)
_Releases_lock_(lockPtr->lock)
static ESIF_INLINE void esif_ccb_write_unlock (esif_ccb_lock_t *lockPtr)
{WdfSpinLockRelease(lockPtr->lock);}
_IRQL_raises_(DISPATCH_LEVEL)
_IRQL_saves_global_(OldIrql, lockPtr)
_Acquires_lock_(lockPtr->lock)
static ESIF_INLINE void esif_ccb_read_lock (esif_ccb_lock_t *lockPtr)
{WdfSpinLockAcquire(lockPtr->lock);}
_IRQL_restores_global_(OldIrql, lockPtr)
_IRQL_requires_(DISPATCH_LEVEL)
_Releases_lock_(lockPtr->lock)
static ESIF_INLINE void esif_ccb_read_unlock (esif_ccb_lock_t *lockPtr)
{WdfSpinLockRelease(lockPtr->lock);}
static ESIF_INLINE void esif_ccb_low_priority_thread_lock_init (
esif_ccb_low_priority_thread_lock_t *lockPtr)
{
/* TODO: Change creation functions to return status and check in code */
NTSTATUS stat;
stat = WdfWaitLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &lockPtr->lock);
NT_SUCCESS(stat);
}
#define esif_ccb_low_priority_thread_lock_uninit(lockPtr) /* not used */
static ESIF_INLINE void esif_ccb_low_priority_thread_write_lock (
esif_ccb_low_priority_thread_lock_t *lockPtr)
{WdfWaitLockAcquire(lockPtr->lock, NULL);} /* Wait forever */
static ESIF_INLINE void esif_ccb_low_priority_thread_write_unlock (
esif_ccb_low_priority_thread_lock_t *lockPtr)
{WdfWaitLockRelease(lockPtr->lock);}
static ESIF_INLINE void esif_ccb_low_priority_thread_read_lock (
esif_ccb_low_priority_thread_lock_t *lockPtr)
{WdfWaitLockAcquire(lockPtr->lock, NULL);} /* Wait forever */
static ESIF_INLINE void esif_ccb_low_priority_thread_read_unlock (
esif_ccb_low_priority_thread_lock_t *lockPtr)
{WdfWaitLockRelease(lockPtr->lock);}
#endif /* ESIF_ATTR_OS_WINDOWS */
#endif /* ESIF_ATTR_KERNEL */
/******************************************************************************
* USER LOCKS
******************************************************************************/
#ifdef ESIF_ATTR_USER
#include "esif.h"
#include "esif_ccb_atomic.h"
/* Spinlock */
typedef atomic_t esif_ccb_spinlock_t;
#define esif_ccb_spinlock_init(lockPtr) *(lockPtr) = ATOMIC_INIT(0)
#define esif_ccb_spinlock_uninit(lockPtr) (lockPtr)
#define esif_ccb_spinlock_lock(lockPtr) while (atomic_set(lockPtr, 1) == 1) {;}
#define esif_ccb_spinlock_unlock(lockPtr) atomic_set(lockPtr, 0)
#ifdef ESIF_ATTR_OS_LINUX
#include <pthread.h>
#define PTHREAD_MUTEX_INIT_TYPE(mutex, type) do { static pthread_mutexattr_t attr; pthread_mutexattr_settype(&attr, type); pthread_mutex_init(mutex, &attr); } while (0)
/* Emulate Critical Section */
typedef pthread_mutex_t esif_ccb_critical_section_t;
#define esif_ccb_critical_section_init(csPtr) PTHREAD_MUTEX_INIT_TYPE(csPtr, PTHREAD_MUTEX_RECURSIVE)
#define esif_ccb_critical_section_uninit(csPtr) pthread_mutex_destroy(csPtr)
#define esif_ccb_critical_section_enter(csPtr) pthread_mutex_lock(csPtr) /* reentrant */
#define esif_ccb_critical_section_leave(csPtr) pthread_mutex_unlock(csPtr) /* reentrant */
/* Mutex */
typedef pthread_mutex_t esif_ccb_mutex_t;
#define esif_ccb_mutex_init(mutexPtr) PTHREAD_MUTEX_INIT_TYPE(mutexPtr, PTHREAD_MUTEX_RECURSIVE)
#define esif_ccb_mutex_uninit(mutexPtr) pthread_mutex_destroy(mutexPtr)
#define esif_ccb_mutex_lock(mutexPtr) pthread_mutex_lock(mutexPtr) /* reentrant */
#define esif_ccb_mutex_unlock(mutexPtr) pthread_mutex_unlock(mutexPtr) /* reentrant */
/* RW Lock */
typedef pthread_rwlock_t esif_ccb_lock_t;
#define esif_ccb_lock_init(lockPtr) pthread_rwlock_init(lockPtr, NULL)
#define esif_ccb_lock_uninit(lockPtr) pthread_rwlock_destroy(lockPtr)
#define esif_ccb_write_lock(lockPtr) pthread_rwlock_wrlock(lockPtr) /* NOT reentrant */
#define esif_ccb_write_unlock(lockPtr) pthread_rwlock_unlock(lockPtr) /* NOT reentrant */
#define esif_ccb_read_lock(lockPtr) pthread_rwlock_rdlock(lockPtr) /* reentrant */
#define esif_ccb_read_unlock(lockPtr) pthread_rwlock_unlock(lockPtr) /* reentrant */
#endif /* ESIF_ATTR_OS_LINUX */
#ifdef ESIF_ATTR_OS_WINDOWS
/* Critical Section */
typedef CRITICAL_SECTION esif_ccb_critical_section_t;
#define esif_ccb_critical_section_init(csPtr) InitializeCriticalSection(csPtr)
#define esif_ccb_critical_section_uninit(csPtr) DeleteCriticalSection(csPtr)
#define esif_ccb_critical_section_enter(csPtr) EnterCriticalSection(csPtr) /* reentrant */
#define esif_ccb_critical_section_leave(csPtr) LeaveCriticalSection(csPtr) /* reentrant */
/* Mutex */
typedef HANDLE esif_ccb_mutex_t;
#define esif_ccb_mutex_init(mutexPtr) *mutexPtr = CreateMutex(NULL, FALSE, NULL)
#define esif_ccb_mutex_uninit(mutexPtr) CloseHandle(*mutexPtr)
#define esif_ccb_mutex_lock(mutexPtr) WaitForSingleObject(*mutexPtr, INFINITE) /* reentrant */
#define esif_ccb_mutex_unlock(mutexPtr) ReleaseMutex(*mutexPtr) /* reentrant */
/* RW Lock */
/* Wrapper for SRWLOCKs to allow nested READ locks in Windows
* This is necessary to avoid WHQL errors and potential deadlocks in Windows
* This is unecessary for Linux since pthread_rwlock_t is read reentrant
*/
typedef struct esif_ccb_lock_s {
SRWLOCK lock; /* Slim Read/Write Lock */
esif_ccb_spinlock_t spinlock; /* Spinlock for managing lock and ref_count */
UInt32 ref_count; /* Count of Acquired References to shared READ lock */
} esif_ccb_lock_t;
/* Initialize */
static ESIF_INLINE void esif_ccb_lock_init(esif_ccb_lock_t *lockPtr)
{
InitializeSRWLock(&lockPtr->lock);
esif_ccb_spinlock_init(&lockPtr->spinlock);
lockPtr->ref_count = 0;
}
/* Uninitialize */
static ESIF_INLINE void esif_ccb_lock_uninit(esif_ccb_lock_t *lockPtr)
{
esif_ccb_spinlock_uninit(&lockPtr->spinlock);
}
/* NOT Reentrant Write Lock */
static ESIF_INLINE void esif_ccb_write_lock(esif_ccb_lock_t *lockPtr)
{
AcquireSRWLockExclusive(&lockPtr->lock);
}
/* NOT Reentrant Write Unlock */
static ESIF_INLINE void esif_ccb_write_unlock(esif_ccb_lock_t *lockPtr)
{
ReleaseSRWLockExclusive(&lockPtr->lock);
}
/* Reentrant Read Lock */
static ESIF_INLINE void esif_ccb_read_lock(esif_ccb_lock_t *lockPtr)
{
BOOL release = FALSE;
/* Acquire spinlock to see if any readers have acquired the lock
* If so just increment ref_count, otherwise Acquire lock outside spinlock
*/
esif_ccb_spinlock_lock(&lockPtr->spinlock);
if (lockPtr->ref_count > 0) {
++lockPtr->ref_count;
}
else {
esif_ccb_spinlock_unlock(&lockPtr->spinlock);
AcquireSRWLockShared(&lockPtr->lock);
/* After acquiring lock, update ref_count after re-acquiring spinlock */
esif_ccb_spinlock_lock(&lockPtr->spinlock);
if (++lockPtr->ref_count > 1) {
release = TRUE;
}
}
esif_ccb_spinlock_unlock(&lockPtr->spinlock);
/* If multiple threads Acquired locks, all but one will release it here */
if (release) {
ReleaseSRWLockShared(&lockPtr->lock);
}
}
/* Reentrant Read Unlock */
static ESIF_INLINE void esif_ccb_read_unlock(esif_ccb_lock_t *lockPtr)
{
BOOL release = FALSE;
/* Aquire spinlock to see if this is the last reader referencing this lock
* If this is the last reader, Release the lock outside of the spinlock
*/
esif_ccb_spinlock_lock(&lockPtr->spinlock);
if (--lockPtr->ref_count == 0) {
release = TRUE;
}
esif_ccb_spinlock_unlock(&lockPtr->spinlock);
if (release) {
ReleaseSRWLockShared(&lockPtr->lock);
}
}
#endif /* ESIF_ATTR_OS_WINDOWS */
#endif /* ESIF_ATTR_USER */
#endif /* _ESIF_CCB_LOCK_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,355 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_CCB_MEMORY_H_
#define _ESIF_CCB_MEMORY_H_
#include "esif_ccb_lock.h"
#ifdef ESIF_ATTR_USER
#include "esif.h"
#include "esif_ccb_atomic.h"
/* Enable Detailed Memory Tracing? */
#ifdef ESIF_ATTR_MEMTRACE
#pragma pack(push,1)
struct memalloc_s {
struct memalloc_s *next;
void *mem_ptr;
size_t size;
const char *func;
const char *file;
int line;
};
struct memtrace_s {
esif_ccb_lock_t lock;
atomic_t allocs;
atomic_t frees;
struct memalloc_s *allocated;
};
#pragma pack(pop)
#ifdef __cplusplus
extern "C" {
#endif
extern struct memtrace_s g_memtrace;
#ifdef __cplusplus
}
#endif
#endif
#endif
/* memstat counters interface */
#if defined(ESIF_ATTR_MEMSTAT_NOLOCK)
# define memstat_inc(intptr) ((*(intptr))++)
# define memstat_read(intptr) (*(intptr))
# define memstat_set(intptr, val) (*(intptr) = (val))
#elif defined(ESIF_ATTR_MEMSTAT_ATOMIC)
/* TODO: Replace Inlines with these after converting g_memstat u32 to atomic_t */
# define memstat_inc(intptr) atomic_inc(intptr)
# define memstat_read(intptr) atomic_read(intptr)
# define memstat_set(intptr, val) atomic_set(intptr, val)
#else
#ifdef __cplusplus
extern "C" {
#endif
extern esif_ccb_lock_t g_memstat_lock;
#ifdef __cplusplus
}
#endif
static ESIF_INLINE void memstat_inc(u32 *intptr)
{
esif_ccb_write_lock(&g_memstat_lock);
(*(intptr))++;
esif_ccb_write_unlock(&g_memstat_lock);
}
static ESIF_INLINE u32 memstat_read(u32 *intptr)
{
u32 rc;
esif_ccb_read_lock(&g_memstat_lock);
rc = *(intptr);
esif_ccb_read_unlock(&g_memstat_lock);
return rc;
}
static ESIF_INLINE void memstat_set(u32 *intptr, u32 val)
{
esif_ccb_write_lock(&g_memstat_lock);
*(intptr) = val;
esif_ccb_write_unlock(&g_memstat_lock);
}
#endif
/* Memory Copy */
static ESIF_INLINE void esif_ccb_memcpy(
void *dest_ptr,
const void *src_ptr,
size_t size
)
{
MEMORY_DEBUG("%s: dest = %p src = %p size = %u\n",
ESIF_FUNC,
dest_ptr,
src_ptr,
size);
#ifdef ESIF_ATTR_KERNEL
#ifdef ESIF_ATTR_OS_WINDOWS
memcpy_s(dest_ptr, size, src_ptr, size);
#endif
#ifdef ESIF_ATTR_OS_LINUX
memcpy(dest_ptr, src_ptr, size);
#endif
#endif
#ifdef ESIF_ATTR_USER
#ifdef ESIF_ATTR_OS_WINDOWS
memcpy_s(dest_ptr, size, src_ptr, size);
#endif
#ifdef ESIF_ATTR_OS_LINUX
memcpy(dest_ptr, src_ptr, size);
#endif
#endif
}
/* Memory Move */
static ESIF_INLINE void esif_ccb_memmove(
void *dest_ptr,
const void *src_ptr,
size_t size
)
{
MEMORY_DEBUG("%s: dest = %p src = %p size = %u\n",
ESIF_FUNC,
dest_ptr,
src_ptr,
size);
#ifdef ESIF_ATTR_KERNEL
#ifdef ESIF_ATTR_OS_WINDOWS
memmove_s(dest_ptr, size, src_ptr, size);
#endif
#ifdef ESIF_ATTR_OS_LINUX
memmove(dest_ptr, src_ptr, size);
#endif
#endif
#ifdef ESIF_ATTR_USER
#ifdef ESIF_ATTR_OS_WINDOWS
memmove_s(dest_ptr, size, src_ptr, size);
#else
memmove(dest_ptr, src_ptr, size);
#endif
#endif
}
/* Memory Set */
static ESIF_INLINE void *esif_ccb_memset(
void *s_ptr,
int c,
size_t count
)
{
MEMORY_DEBUG("%s: dest = %p value = %02x size = %u\n",
ESIF_FUNC,
s_ptr,
c,
count);
return memset(s_ptr, c, count);
}
#ifdef ESIF_ATTR_MEMTRACE
#ifdef __cplusplus
extern "C" {
#endif
extern void *esif_memtrace_alloc(void *old_ptr, size_t size, const char *func, const char *file, int line);
extern void esif_memtrace_free(void *mem_ptr);
extern void esif_memtrace_init();
extern void esif_memtrace_exit();
#ifdef __cplusplus
}
#endif
#define esif_ccb_malloc(size) esif_memtrace_alloc(0, size, __FUNCTION__, __FILE__, __LINE__)
#define esif_ccb_realloc(old_ptr, size) esif_memtrace_alloc(old_ptr, size, __FUNCTION__, __FILE__, __LINE__)
#define esif_ccb_free(mem_ptr) esif_memtrace_free(mem_ptr)
#else
/* Memory Allocate */
static ESIF_INLINE void
*esif_ccb_malloc(size_t size)
{
void *mem_ptr = NULL;
#ifdef ESIF_ATTR_KERNEL
/* Linux */
#ifdef ESIF_ATTR_OS_LINUX
mem_ptr = kzalloc(size, GFP_ATOMIC);
#endif
/* Windows */
#ifdef ESIF_ATTR_OS_WINDOWS
mem_ptr = ExAllocatePoolWithTag(NonPagedPool,
size,
ESIF_MEMPOOL_FW_MALLOC);
if (NULL != mem_ptr)
esif_ccb_memset(mem_ptr, 0, size);
#endif
#ifndef ESIF_ATTR_OS_LINUX_DRIVER
memstat_inc(&g_memstat.allocs);
#endif
#endif /* ESIF_ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
mem_ptr = malloc(size);
if (NULL != mem_ptr)
esif_ccb_memset(mem_ptr, 0, size);
#endif /* ESIF_ATTR_USER */
MEMORY_DEBUG("%s: buf %p size = %u\n", ESIF_FUNC, mem_ptr, size);
return mem_ptr;
}
/* Memory Free */
static ESIF_INLINE
void esif_ccb_free(void *mem_ptr)
{
MEMORY_DEBUG("%s: buf %p\n", ESIF_FUNC, mem_ptr);
#ifdef ESIF_ATTR_KERNEL
/* Linux */
#ifdef ESIF_ATTR_OS_LINUX
kfree(mem_ptr);
#endif
/* Windows */
#ifdef ESIF_ATTR_OS_WINDOWS
ExFreePoolWithTag(mem_ptr, ESIF_MEMPOOL_FW_MALLOC);
mem_ptr = NULL;
#endif
#ifndef ESIF_ATTR_OS_LINUX_DRIVER
memstat_inc(&g_memstat.frees);
#endif
#endif /* ESIF_ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
if (NULL != mem_ptr)
free(mem_ptr);
#endif /* ESIF_ATTR_USER */
}
/* Memory Reallocate */
static ESIF_INLINE void *esif_ccb_realloc(
void *mem_ptr,
size_t new_size
)
{
#ifdef ESIF_ATTR_USER
void *old_ptr = mem_ptr;
#endif
MEMORY_DEBUG("%s: buf %p, new_size=%lld\n", ESIF_FUNC, mem_ptr,
(long long)new_size);
#ifdef ESIF_ATTR_KERNEL
UNREFERENCED_PARAMETER(mem_ptr);
UNREFERENCED_PARAMETER(new_size);
return 0; /* Not Implemented in Kernel space */
#endif /* ESIF_ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
mem_ptr = realloc(mem_ptr, new_size);
if (NULL == old_ptr && NULL != mem_ptr)
esif_ccb_memset(mem_ptr, 0, new_size);
return mem_ptr;
#endif
}
#endif /* ESIF_ATTR_MEMTRACE */
/* Memory Dump */
static ESIF_INLINE void esif_ccb_mem_dump(
const u8 *ch,
const u8 *what,
const int size
)
{
int i;
UNREFERENCED_PARAMETER(what);
MEMORY_DEBUG("%s: Dumping Memory for %s\n", ESIF_FUNC, what);
for (i = 0; i < size; i++, ch++)
MEMORY_DEBUG("<%p> 0x%02X\n", (u8 *)ch, (u8)*ch);
MEMORY_DEBUG("End of Memory Dump\n");
}
#endif /* _ESIF_CCB_MEMORY_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,498 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_CCB_MEMPOOL_H_
#define _ESIF_CCB_MEMPOOL_H_
#ifdef __cplusplus
extern "C" {
#endif
extern esif_ccb_lock_t g_mempool_lock;
#ifdef __cplusplus
}
#endif
#ifdef ESIF_ATTR_KERNEL
struct esif_ccb_mempool {
#ifdef ESIF_ATTR_OS_LINUX
struct kmem_cache *cache;
#endif /* Linux */
#ifdef ESIF_ATTR_OS_WINDOWS
/* TODO: Look aside List? */
#endif /* Windows */
esif_string name_ptr; /* Name */
u32 pool_tag; /* Pool Tag */
u32 object_size; /* Size Of Pool Object In Bytes */
u32 alloc_count; /* Object Allocation Count */
u32 free_count; /* Object Free Count */
};
/* Memory Pool Create */
static ESIF_INLINE struct esif_ccb_mempool *esif_ccb_mempool_create(
enum esif_mempool_type pool_type,
u32 pool_tag,
u32 object_size
)
{
struct esif_ccb_mempool *pool_ptr = NULL;
if (pool_type >= ESIF_MEMPOOL_TYPE_MAX)
goto exit;
pool_ptr = (struct esif_ccb_mempool *)
esif_ccb_malloc(sizeof(*pool_ptr));
if (NULL == pool_ptr)
return NULL;
pool_ptr->name_ptr = esif_mempool_str(pool_tag);
pool_ptr->pool_tag = pool_tag;
pool_ptr->alloc_count = 0;
pool_ptr->free_count = 0;
pool_ptr->object_size = object_size;
#ifdef ESIF_ATTR_OS_LINUX
pool_ptr->cache = kmem_cache_create(pool_ptr->name_ptr,
pool_ptr->object_size,
0,
SLAB_HWCACHE_ALIGN,
NULL);
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
/* TODO Look aside List? */
#endif
esif_ccb_write_lock(&g_mempool_lock);
g_mempool[pool_type] = pool_ptr;
memstat_inc(&g_memstat.memPoolAllocs);
MEMPOOL_DEBUG("%s: Memory Pool %s Create Object Size=%d\n", ESIF_FUNC,
pool_ptr->name_ptr, pool_ptr->object_size);
esif_ccb_write_unlock(&g_mempool_lock);
exit:
return pool_ptr;
}
/* Memory Pool Destroy */
static ESIF_INLINE void esif_ccb_mempool_destroy(
enum esif_mempool_type pool_type
)
{
struct esif_ccb_mempool *pool_ptr = NULL;
int remain = 0;
if (pool_type >= ESIF_MEMPOOL_TYPE_MAX)
goto exit;
esif_ccb_write_lock(&g_mempool_lock);
pool_ptr = g_mempool[pool_type];
if (NULL == pool_ptr) {
esif_ccb_write_unlock(&g_mempool_lock);
goto exit;
}
remain = pool_ptr->alloc_count - pool_ptr->free_count;
MEMPOOL_DEBUG("%s: Memory Pool %s Destroy alloc=%d free=%d remain=%d\n",
ESIF_FUNC,
pool_ptr->name_ptr,
pool_ptr->alloc_count,
pool_ptr->free_count,
remain);
#ifdef ESIF_ATTR_OS_LINUX
if (NULL != pool_ptr->cache)
kmem_cache_destroy(pool_ptr->cache);
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
/* Nothing To Do */
#endif
g_mempool[pool_type] = NULL;
memstat_inc(&g_memstat.memPoolFrees);
esif_ccb_write_unlock(&g_mempool_lock);
esif_ccb_free(pool_ptr);
exit:
;
}
/* Memory Pool Alloc */
static ESIF_INLINE void *esif_ccb_mempool_alloc(
enum esif_mempool_type pool_type
)
{
struct esif_ccb_mempool *pool_ptr = NULL;
void *mem_ptr = NULL;
if (pool_type >= ESIF_MEMPOOL_TYPE_MAX)
goto exit;
esif_ccb_write_lock(&g_mempool_lock);
pool_ptr = g_mempool[pool_type];
if (NULL == pool_ptr) {
esif_ccb_write_unlock(&g_mempool_lock);
goto exit;
}
#ifdef ESIF_ATTR_OS_LINUX
mem_ptr = kmem_cache_alloc(pool_ptr->cache, GFP_ATOMIC);
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
mem_ptr = ExAllocatePoolWithTag(NonPagedPool,
pool_ptr->object_size,
pool_ptr->pool_tag);
#endif
if (NULL == mem_ptr) {
esif_ccb_write_unlock(&g_mempool_lock);
goto exit;
}
pool_ptr->alloc_count++;
memstat_inc(&g_memstat.memPoolObjAllocs);
MEMPOOL_DEBUG("%s: MP Entry Allocated(%d)=%p From Mempool %s\n",
ESIF_FUNC,
pool_ptr->alloc_count,
mem_ptr,
pool_ptr->name_ptr);
esif_ccb_write_unlock(&g_mempool_lock);
exit:
return mem_ptr;
}
/* Memory Pool Free */
static ESIF_INLINE void esif_ccb_mempool_free(
enum esif_mempool_type pool_type,
void *mem_ptr
)
{
struct esif_ccb_mempool *pool_ptr = NULL;
if ((NULL == mem_ptr) || (pool_type >= ESIF_MEMPOOL_TYPE_MAX))
goto exit;
esif_ccb_write_lock(&g_mempool_lock);
pool_ptr = g_mempool[pool_type];
if (NULL == pool_ptr) {
esif_ccb_write_unlock(&g_mempool_lock);
goto exit;
}
#ifdef ESIF_ATTR_OS_LINUX
kmem_cache_free(pool_ptr->cache, mem_ptr);
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
ExFreePoolWithTag(mem_ptr, pool_ptr->pool_tag);
#endif
pool_ptr->free_count++;
memstat_inc(&g_memstat.memPoolObjFrees);
MEMPOOL_DEBUG("%s: MP Entry Freed(%d)=%p From Mempool %s\n", ESIF_FUNC,
pool_ptr->free_count, mem_ptr, pool_ptr->name);
esif_ccb_write_unlock(&g_mempool_lock);
exit:
;
}
#endif /* ESIF_ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
#include "esif.h"
#pragma pack(push,1)
struct esif_ccb_mempool {
esif_string name_ptr; /* Name */
UInt32 pool_tag; /* Pool Tag */
UInt32 object_size; /* Size Of Pool Object In Bytes */
UInt32 alloc_count; /* Object Allocation Count */
UInt32 free_count; /* Object Free Count */
};
#pragma pack(pop)
/* Memory Pool Create */
static ESIF_INLINE struct esif_ccb_mempool *esif_ccb_mempool_create(
enum esif_mempool_type pool_type,
UInt32 pool_tag,
UInt32 object_size
)
{
struct esif_ccb_mempool *pool_ptr = NULL;
if (pool_type >= ESIF_MEMPOOL_TYPE_MAX)
goto exit;
pool_ptr = (struct esif_ccb_mempool *)
esif_ccb_malloc(sizeof(*pool_ptr));
if (NULL == pool_ptr)
return NULL;
pool_ptr->name_ptr = esif_mempool_str(pool_tag);
pool_ptr->pool_tag = pool_tag;
pool_ptr->alloc_count = 0;
pool_ptr->free_count = 0;
pool_ptr->object_size = object_size;
esif_ccb_write_lock(&g_mempool_lock);
g_mempool[pool_type] = pool_ptr;
MEMPOOL_DEBUG("%s: Memory Pool %s Create Object Size=%d\n", ESIF_FUNC,
pool_ptr->name_ptr, pool_ptr->object_size);
esif_ccb_write_unlock(&g_mempool_lock);
exit:
return pool_ptr;
}
/* Memory Pool Destroy */
static ESIF_INLINE void esif_ccb_mempool_destroy(
enum esif_mempool_type pool_type
)
{
struct esif_ccb_mempool *pool_ptr = NULL;
int remain = 0;
if (pool_type >= ESIF_MEMPOOL_TYPE_MAX)
goto exit;
esif_ccb_write_lock(&g_mempool_lock);
pool_ptr = g_mempool[pool_type];
if (NULL == pool_ptr) {
esif_ccb_write_unlock(&g_mempool_lock);
goto exit;
}
remain = pool_ptr->alloc_count - pool_ptr->free_count;
MEMPOOL_DEBUG("%s: Memory Pool %s Destroy alloc=%d free=%d remain=%d\n",
ESIF_FUNC,
pool_ptr->name_ptr,
pool_ptr->alloc_count,
pool_ptr->free_count,
remain);
g_mempool[pool_type] = NULL;
esif_ccb_write_unlock(&g_mempool_lock);
esif_ccb_free(pool_ptr);
exit:
;
}
/* Memory Pool Alloc */
static ESIF_INLINE void *esif_ccb_mempool_alloc(
enum esif_mempool_type pool_type
)
{
struct esif_ccb_mempool *pool_ptr = NULL;
void *mem_ptr = NULL;
if (pool_type >= ESIF_MEMPOOL_TYPE_MAX)
goto exit;
esif_ccb_write_lock(&g_mempool_lock);
pool_ptr = g_mempool[pool_type];
if (NULL == pool_ptr) {
esif_ccb_write_unlock(&g_mempool_lock);
goto exit;
}
mem_ptr = esif_ccb_malloc(pool_ptr->object_size);
if (NULL == mem_ptr) {
esif_ccb_write_unlock(&g_mempool_lock);
goto exit;
}
pool_ptr->alloc_count++;
MEMPOOL_DEBUG("%s: MP Entry Allocated(%d)=%p From Mempool %s\n",
ESIF_FUNC,
pool_ptr->alloc_count,
mem_ptr,
pool_ptr->name_ptr);
esif_ccb_write_unlock(&g_mempool_lock);
exit:
return mem_ptr;
}
/* Memory Pool Free */
static ESIF_INLINE void esif_ccb_mempool_free(
enum esif_mempool_type pool_type,
void *mem_ptr
)
{
struct esif_ccb_mempool *pool_ptr = NULL;
if (mem_ptr != NULL)
esif_ccb_free(mem_ptr);
if (pool_type >= ESIF_MEMPOOL_TYPE_MAX)
goto exit;
esif_ccb_write_lock(&g_mempool_lock);
pool_ptr = g_mempool[pool_type];
if (NULL == pool_ptr) {
esif_ccb_write_unlock(&g_mempool_lock);
goto exit;
}
pool_ptr->free_count++;
MEMPOOL_DEBUG("%s: MP Entry Freed(%d)=%p From Mempool %s\n", ESIF_FUNC,
pool_ptr->free_count, mem_ptr, pool_ptr->name_ptr);
esif_ccb_write_unlock(&g_mempool_lock);
exit:
;
}
#endif /* ESIF_ATTR_USER */
/* NOTE: This function is common to user and kernel mode */
static ESIF_INLINE void esif_ccb_mempool_init_tracking(void)
{
esif_ccb_lock_init(&g_mempool_lock);
}
/* NOTE: This function is common to user and kernel mode */
static ESIF_INLINE void esif_ccb_mempool_uninit_tracking(void)
{
u32 type_tag;
/*
* Create the tracking array for all supported types.
*/
for (type_tag = 0; type_tag < ESIF_MEMPOOL_TYPE_MAX; type_tag++)
esif_ccb_mempool_destroy((enum esif_mempool_type)type_tag);
esif_ccb_lock_uninit(&g_mempool_lock);
}
/* Memory Pool ZERO Alloc */
/* NOTE: This function is common to user and kernel mode */
static ESIF_INLINE void *esif_ccb_mempool_zalloc(
enum esif_mempool_type pool_type
)
{
struct esif_ccb_mempool *pool_ptr = NULL;
void *mem_ptr = NULL;
mem_ptr = esif_ccb_mempool_alloc(pool_type);
if (NULL == mem_ptr)
goto exit;
/*
* If the allocation above is successful, we know the pool_type is in
* bounds, so no check required in this function.
*/
esif_ccb_read_lock(&g_mempool_lock);
pool_ptr = g_mempool[pool_type];
if (NULL == pool_ptr) {
esif_ccb_read_unlock(&g_mempool_lock);
esif_ccb_mempool_free(pool_type, mem_ptr);
mem_ptr = NULL;
goto exit;
}
esif_ccb_memset(mem_ptr, 0, pool_ptr->object_size);
esif_ccb_read_unlock(&g_mempool_lock);
exit:
return mem_ptr;
}
#endif /* _ESIF_CCB_MEMPOOL_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,159 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_CCB_SEM_H_
#define _ESIF_CCB_SEM_H_
#ifdef ESIF_ATTR_KERNEL
#ifdef ESIF_ATTR_OS_LINUX
typedef struct semaphore esif_ccb_sem_t;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
#define esif_ccb_sem_init(semPtr) sema_init(semPtr, 0)
#else /* linux version else */
#define esif_ccb_sem_init(semPtr) init_MUTEX_LOCKED(semPtr)
#endif /* LINUX_VERSION_CODE */
#define esif_ccb_sem_uninit(semPtr)
#define esif_ccb_sem_up(semPtr) up(semPtr)
#define esif_ccb_sem_down(semPtr) down(semPtr)
static ESIF_INLINE int esif_ccb_sem_try_down (
esif_ccb_sem_t *sem_ptr,
u32 us_timeout
)
{
return down_timeout(sem_ptr, usecs_to_jiffies(us_timeout));
}
#endif /* ESIF_ATTR_OS_LINUX */
#ifdef ESIF_ATTR_OS_WINDOWS
typedef u32 esif_ccb_sem_t;
#define esif_ccb_sem_init(semPtr)
#define esif_ccb_sem_uninit(semPtr)
#define esif_ccb_sem_up(semPtr)
#define esif_ccb_sem_down(semPtr)
static ESIF_INLINE int esif_ccb_sem_try_down (
esif_ccb_sem_t *sem_ptr,
u32 us_timeout
)
{
UNREFERENCED_PARAMETER(sem_ptr);
UNREFERENCED_PARAMETER(us_timeout);
return 0;
}
#endif /* ESIF_ATTR_OS_WINDOWS */
#endif /* ESIF_ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
#include "esif.h"
#ifdef ESIF_ATTR_OS_LINUX
#include <semaphore.h>
/* Semphore */
typedef sem_t esif_ccb_sem_t;
#define esif_ccb_sem_init(semPtr) sem_init(semPtr, 0, 0)
#define esif_ccb_sem_uninit(semPtr) sem_destroy(semPtr)
#define esif_ccb_sem_up(semPtr) sem_wait(semPtr)
#define esif_ccb_sem_down(semPtr) sem_post(semPtr)
/* Event */
typedef sem_t esif_ccb_event_t;
#define esif_ccb_event_create(eventPtr) sem_init(eventPtr, 0, 0)
#define esif_ccb_event_destroy(eventPtr) sem_destroy(semPtr)
#define esif_ccb_event_set(eventPtr) sem_wait(*eventPtr)
#define esif_ccb_event_reset(eventPtr) sem_post(*eventPtr)
/* Conditional Variable */
typedef pthread_cond_t esif_ccb_cond_t;
#define esif_ccb_cond_init(cond) pthread_cond_init(cond, NULL)
#define esif_ccb_cond_destroy pthread_cond_destroy
#define esif_ccb_cond_wait pthread_cond_wait
#define esif_ccb_cond_signal pthread_cond_signal
#define esif_ccb_cond_broadcast pthread_cond_broadcast
#endif /* ESIF_ATTR_OS_LINUX */
#ifdef ESIF_ATTR_OS_WINDOWS
/* Semaphore */
typedef HANDLE esif_ccb_sem_t;
#define esif_ccb_sem_init(semPtr) *semPtr = CreateSemaphore(NULL, 0, \
0x7fffffff, NULL)
#define esif_ccb_sem_uninit(semPtr) CloseHandle(*semPtr)
#define esif_ccb_sem_up(semPtr) WaitForSingleObject(*semPtr, INFINITE)
#define esif_ccb_sem_down(semPtr) ReleaseSemaphore(*semPtr, 1, NULL)
/* Event */
typedef HANDLE esif_ccb_event_t;
#define esif_ccb_event_create(eventPtr) *eventPtr = CreateEvent(NULL, FALSE, \
FALSE, NULL)
#define esif_ccb_event_destroy(eventPtr) CloseHandle(*eventPtr)
#define esif_ccb_event_set(eventPtr) SetEvent(*eventPtr)
#define esif_ccb_event_reset(eventPtr) ResetEvent(*eventPtr)
#endif /* ESIF_ATTR_OS_WINDOWS */
#endif /* ESIF_ATTR_USER */
#endif /* _ESIF_CCB_SEM_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,372 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_CCB_STRING_H_
#define _ESIF_CCB_STRING_H_
#ifdef ESIF_ATTR_USER
#include "esif.h"
#endif
/*****************************************************************************
** KERNEL
*/
#ifdef ESIF_ATTR_KERNEL
static ESIF_INLINE int esif_acpi_get_strlen(
const u16 type,
const u32 is_unicode,
u16 str_len
)
{
if (is_unicode) {
return str_len / 2; /* All Unicode shall contain
*null-terminated code */
}
#ifdef ESIF_ATTR_OS_LINUX
if (type == ACPI_TYPE_STRING) {
return str_len + 1; /* Linux ascii doesn't have
*null-terminated byte, so append one */
} else {
return str_len; /* Buffer type, len should be as it is */
}
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
UNREFERENCED_PARAMETER(type);
return str_len; /* Windows ascii ALWAYS contain null-term byte */
#endif
}
static ESIF_INLINE int esif_ccb_is_unicode(const u32 acpi_method)
{
/*
* 0) Rules applying to both Windows and Linux.
* 1) Unicode only exists in ACPI buffer, but not in ACPI string.
* 2) The only known unicode method is '_STR', need to convert it to
*ascii.
* 3) Others such as GUID in 'IDSP' are binary (hex), no need to
*convert.
*/
switch (acpi_method) {
case 'RTS_': /* 0x5254535f: _STR */
return 1;
default:
return 0;
}
}
static ESIF_INLINE void esif_ccb_uni2ascii(
char *string_ptr,
int buflen,
u8 *unicode_ptr,
int unicode_size
)
{
#ifdef ESIF_ATTR_OS_LINUX
int i;
__le16 *le16unicode_ptr = (__le16 *)unicode_ptr;
if (buflen <= 0) /* never happens, but... */
return;
--buflen; /* space for nul */
for (i = 0; i < unicode_size; i++) {
if (i >= buflen)
break;
string_ptr[i] = (char)(le16_to_cpu(le16unicode_ptr[i]));
}
string_ptr[i] = 0x00;
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
UNICODE_STRING us_val;
ANSI_STRING ansi_val;
NTSTATUS status;
UNREFERENCED_PARAMETER(unicode_size);
if (buflen <= 0)
return;
RtlInitUnicodeString(&us_val, (PCWSTR)unicode_ptr);
status = RtlUnicodeStringToAnsiString(&ansi_val,
&us_val,
TRUE /* Allocate ANSI String */);
if (!NT_SUCCESS(status) || (NULL == ansi_val.Buffer))
return;
buflen = min(ansi_val.Length, buflen);
esif_ccb_memcpy(string_ptr, ansi_val.Buffer, buflen);
string_ptr[buflen - 1];
RtlFreeAnsiString(&ansi_val);
#endif
}
#ifdef ESIF_ATTR_OS_WINDOWS
#include <ntstrsafe.h>
#define esif_ccb_sprintf(siz, str, fmt, ...) \
RtlStringCbPrintfA((NTSTRSAFE_PSTR)str, (size_t)siz, fmt, ##__VA_ARGS__)
#define esif_acpi_memcpy(out, in, len) esif_ccb_memcpy(out, &in, len)
#define esif_acpi_uni2ascii(out, out_len, in, in_len) \
esif_ccb_uni2ascii((char *)out, out_len, (u8 *)&in, in_len)
#endif /* ESIF_ATTR_OS_WINDOWS */
#ifdef ESIF_ATTR_OS_LINUX
#define esif_ccb_sprintf(siz, str, fmt, ...) sprintf(str, fmt, ##__VA_ARGS__)
#define esif_acpi_memcpy(out, in, len) esif_ccb_memcpy(out, in, len)
#define esif_acpi_uni2ascii(out, out_len, in, in_len) \
esif_ccb_uni2ascii(out, out_len, in, in_len)
#endif
/*****************************************************************************
** USER SPACE
*/
#else
#ifdef ESIF_ATTR_OS_WINDOWS
#define esif_ccb_sprintf(size, str, fmt, ...) \
sprintf_s(str, (size_t)size, fmt, ##__VA_ARGS__)
#define esif_ccb_vsprintf(size, str, fmt, ...) \
vsnprintf_s(str, (size_t)size, _TRUNCATE, fmt, ##__VA_ARGS__)
#define esif_ccb_sscanf(str, fmt, ...) sscanf_s(str, fmt, ##__VA_ARGS__)
#define esif_ccb_strtok(str, sep, ctxt) strtok_s(str, sep, ctxt)
#define esif_ccb_strcmp(s1, s2) strcmp(s1, s2)
#define esif_ccb_stricmp(s1, s2) _stricmp(s1, s2)
#define esif_ccb_strncmp(s1, s2, count) strncmp(s1, s2, count)
#define esif_ccb_strnicmp(s1, s2, cnt) _strnicmp(s1, s2, cnt)
#define esif_ccb_strstr(str, sub) strstr(str, sub)
#define esif_ccb_strchr(str, chr) strchr(str, chr)
#define esif_ccb_strrchr(str, chr) strrchr(str, chr)
#define esif_ccb_strlen(str, siz) strnlen_s(str, siz)
#define esif_ccb_wcslen(str, siz) wcsnlen_s(str, siz)
#define esif_ccb_strdup_notrace(str) _strdup(str)
#define esif_ccb_strupr(s, count) _strupr_s(s, count)
#define esif_ccb_strlwr(s, count) _strlwr_s(s, count)
#define esif_ccb_vscprintf(fmt, args) _vscprintf(fmt, args)
#endif
#ifdef ESIF_ATTR_OS_LINUX
#include <ctype.h>
#include <stdarg.h>
#define esif_ccb_sprintf(siz, str, fmt, ...) sprintf(str, fmt, ##__VA_ARGS__)
#define esif_ccb_vsprintf(siz, str, fmt, ...) vsprintf(str, fmt, ##__VA_ARGS__)
#define esif_ccb_sscanf(str, fmt, var, ...) sscanf(str, fmt, var)
#define esif_ccb_strtok(str, sep, ctxt) strtok(str, sep)
#define esif_ccb_strcmp(s1, s2) strcmp(s1, s2)
#define esif_ccb_stricmp(s1, s2) strcasecmp(s1, s2)
#define esif_ccb_strncmp(s1, s2, count) strncmp(s1, s2, count)
#define esif_ccb_strnicmp(s1, s2, cnt) strncasecmp(s1, s2, cnt)
#define esif_ccb_strstr(str, sub) strstr(str, sub)
#define esif_ccb_strchr(str, chr) strchr(str, chr)
#define esif_ccb_strrchr(str, chr) strrchr(str, chr)
#define esif_ccb_strlen(str, siz) strlen(str)
#define esif_ccb_strdup_notrace(str) strdup(str)
/* Linux _strupr_s() equlivalent */
static ESIF_INLINE void esif_ccb_strupr(
char *s,
size_t count
)
{
for (; *s && count; s++, count--)
*s = toupper(*s);
}
/* Linux _strlwr_s() equlivalent */
static ESIF_INLINE void esif_ccb_strlwr(
char *s,
size_t count
)
{
for (; s && *s && count; s++, count--)
*s = tolower(*s);
}
/* Linux _vscprintf() equivalient */
static ESIF_INLINE int esif_ccb_vscprintf(
const char *format,
va_list args
)
{
int retval;
va_list argcopy;
va_copy(argcopy, args);
retval = vsnprintf(0, 0, format, argcopy);
va_end(argcopy);
return retval;
}
#endif
// sprintf and concatentate results to the end of a string
static ESIF_INLINE int esif_ccb_sprintf_concat(
size_t siz, // total size of str buffer, including existing string
char *str, // null terminated string
const char *fmt, // format string
...)
{
int rc = 0;
size_t len = esif_ccb_strlen(str, siz);
va_list args;
va_start(args, fmt);
rc = esif_ccb_vsprintf(siz - len, str + len, fmt, args);
va_end(args);
return rc;
}
#ifdef ESIF_ATTR_MEMTRACE
#ifdef __cplusplus
extern "C" {
#endif
extern char *esif_memtrace_strdup(char *str, const char *func, const char *file, int line);
#ifdef __cplusplus
}
#endif
# define esif_ccb_strdup(str) esif_memtrace_strdup(str, __FUNCTION__, __FILE__, __LINE__)
#else
# define esif_ccb_strdup(str) esif_ccb_strdup_notrace(str)
#endif
#endif /* ESIF_ATTR_USER */
/*****************************************************************************
** Agnostic
*/
#ifdef ESIF_ATTR_OS_WINDOWS
#define esif_ccb_strcpy(dst, src, siz) strncpy_s(dst, siz, src, _TRUNCATE)
#define esif_ccb_strcat(dst, src, siz) strcat_s(dst, siz, src)
#endif
#ifdef ESIF_ATTR_OS_LINUX
/*
* #define esif_ccb_strcpy(dst, src, siz) { strncpy(dst, src, siz); if (siz)
* ((char*)dst)[(siz)-1]=0; }
* Linux strncpy_s equivalent
*/
static ESIF_INLINE void esif_ccb_strcpy(
char *dst,
const char *src,
size_t siz
)
{
strncpy(dst, src, siz);
if (siz)
dst[siz - 1] = 0;
}
#define esif_ccb_strcat(dst, src, size) strcat(dst, src)
#endif
#define esif_ccb_max(a, b) ((a) >= (b) ? (a) : (b))
#define esif_ccb_min(a, b) ((a) <= (b) ? (a) : (b))
/*
** GUID - Requires 32 Byte Buffer
*/
#ifdef ESIF_ATTR_USER
#define ESIF_GUID_PRINT_SIZE 64
static ESIF_INLINE esif_string esif_guid_print(
esif_guid_t *guid,
esif_string buf
)
{
u8 *ptr = (u8 *)guid;
esif_ccb_sprintf(64,
buf,
"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
*ptr,
*(ptr + 1),
*(ptr + 2),
*(ptr + 3),
*(ptr + 4),
*(ptr + 5),
*(ptr + 6),
*(ptr + 7),
*(ptr + 8),
*(ptr + 9),
*(ptr + 10),
*(ptr + 11),
*(ptr + 12),
*(ptr + 13),
*(ptr + 14),
*(ptr + 15)
);
return buf;
}
#endif
#endif /* _ESIF_CCB_STRING_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,209 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_CCB_TIME_H_
#define _ESIF_CCB_TIME_H_
/* Agnostic */
typedef u64 esif_ccb_time_t;
/*
** Return system Time In Milliseconds
*/
/* Kernel */
#ifdef ESIF_ATTR_KERNEL
#ifdef ESIF_ATTR_OS_LINUX
static void ESIF_INLINE esif_ccb_system_time(esif_ccb_time_t *time)
{
struct timeval now = {0};
do_gettimeofday(&now);
*time = (now.tv_sec * 1000); /* Convert sec to msec */
*time += (now.tv_usec / 1000); /* Convert usec to msec */
}
#endif /* ESIF_ATTR_OS_LINUX */
#ifdef ESIF_ATTR_OS_WINDOWS
static void ESIF_INLINE esif_ccb_system_time(esif_ccb_time_t *time)
{
LARGE_INTEGER tickPerSecond = {0};
LARGE_INTEGER tick = {0};
/* get the high resolution counter's accuracy and tick's / sec */
tick = KeQueryPerformanceCounter(&tickPerSecond);
/* sytem time in msec not wall clock */
*time = (tick.QuadPart / (tickPerSecond.QuadPart / 1000));
}
#endif /* ESIF_ATTR_OS_WINDOWS */
#endif /* ESIF_ATTR_KERNEL */
/*
** User
*/
#ifdef ESIF_ATTR_USER
#include "esif.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define MAX_CTIME_LEN 30 /* max length of ctime string */
#ifdef ESIF_ATTR_OS_LINUX
#include <sys/time.h>
#include <errno.h>
static void ESIF_INLINE esif_ccb_ctime(
EsifString time_str,
size_t len,
const time_t *time
)
{
ctime_r(time, time_str);
}
static void ESIF_INLINE esif_ccb_system_time(esif_ccb_time_t *time)
{
struct timeval now = {0};
gettimeofday(&now, NULL);
*time = (now.tv_sec * 1000); /* Convert sec to msec */
*time += (now.tv_usec / 1000); /* Convert usec to msec */
}
static void ESIF_INLINE esif_ccb_get_time(struct timeval *tv)
{
gettimeofday(tv, NULL);
}
static int ESIF_INLINE esif_ccb_localtime(
struct tm *tm_ptr,
const time_t *time
)
{
return (localtime_r(time, tm_ptr) != NULL ? 0 : EINVAL);
}
#endif /* ESIF_ATTR_OS_LINUX */
#ifdef ESIF_ATTR_OS_WINDOWS
static void ESIF_INLINE esif_ccb_ctime(
esif_string time_str,
size_t len,
const time_t *time
)
{
ctime_s(time_str, len, time);
}
static void ESIF_INLINE esif_ccb_system_time(esif_ccb_time_t *time)
{
LARGE_INTEGER tickPerSecond = {0};
LARGE_INTEGER tick = {0};
/* get the high resolution counter's accuracy and tick / sec */
QueryPerformanceFrequency(&tickPerSecond);
QueryPerformanceCounter(&tick);
/* sytem time in msec not wall clock */
*time = (tick.QuadPart / (tickPerSecond.QuadPart / 1000));
}
static void ESIF_INLINE esif_ccb_get_time(struct timeval *tv)
{
LARGE_INTEGER tickPerSecond = {0};
LARGE_INTEGER tick = {0};
time_t rawtime;
/* Get Seconds */
time(&rawtime);
tv->tv_sec = (long)rawtime;
/* get the high resolution counter's accuracy and tick/sec */
QueryPerformanceFrequency(&tickPerSecond);
QueryPerformanceCounter(&tick);
/* Get usec */
tv->tv_usec =
(long)(tick.QuadPart / (tickPerSecond.QuadPart / 1000000));
}
static int ESIF_INLINE esif_ccb_localtime(
struct tm *tm_ptr,
const time_t *time
)
{
return localtime_s(tm_ptr, time);
}
#endif /* ESIF_ATTR_OS_WINDOWS */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ESIF_ATTR_USER */
#endif /* _ESIF_CCB_TIME_H_ */
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/

View File

@@ -0,0 +1,893 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_CCB_TIMER_H_
#define _ESIF_CCB_TIMER_H_
#include "esif_ccb_lock.h"
#include "esif_ccb_sem.h"
#ifdef ESIF_ATTR_OS_WINDOWS
#ifdef ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS
/*
* Coalescable timer options
*/
#define TOLERABLE_DELAY_DIVISOR 10 /* timeout divisor */
#define TOLERABLE_DELAY_INCREMENT 50 /* ms */
#define DUE_TIME_MS_CONV_FACTOR 10000
#endif
#endif
/******************************************************************************
* KERNEL TIMER
******************************************************************************/
#ifdef ESIF_ATTR_KERNEL
/* Timer Callback Function */
typedef void (*esif_ccb_timer_cb)(void *context);
/*
* Timer Is Defined to be opaue here to acoomondate different
* OS and implementation approaches for timers
*/
#ifdef ESIF_ATTR_OS_LINUX
typedef struct {
struct delayed_work work;
esif_ccb_timer_cb function_ptr;
esif_ccb_low_priority_thread_lock_t context_lock;
u32 exit_flag;
u32 timer_period_msec;
u32 periodic_flag;
void *context_ptr;
} esif_ccb_timer_t;
#endif /* ESIF_ATTR_OS_LINUX */
#ifdef ESIF_ATTR_OS_WINDOWS
typedef struct {
esif_ccb_timer_cb function_ptr;
esif_ccb_low_priority_thread_lock_t context_lock;
u32 exit_flag;
esif_ccb_time_t timer_period_msec;
u32 periodic_flag;
void *context_ptr;
} esif_ccb_timer_context_t;
#ifdef ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS
typedef struct esif_ccb_timer {
KTIMER timer;
KDPC dpc;
esif_ccb_timer_context_t timer_context;
} esif_ccb_timer_t;
typedef struct esif_ccb_work_item_context {
void *ptr;
} esif_ccb_work_item_context_t;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(esif_ccb_work_item_context_t,
esif_ccb_get_work_item_context)
#else
typedef WDFTIMER esif_ccb_timer_t;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(esif_ccb_timer_context_t,
esif_ccb_get_timer_context)
#endif
#endif /* ESIF_ATTR_OS_WINDOWS */
static enum esif_rc esif_ccb_timer_set_msec(
esif_ccb_timer_t *timer_ptr,
esif_ccb_time_t timeout,
esif_flags_t periodic,
esif_ccb_timer_cb function_ptr,
void *context_ptr
);
#ifdef ESIF_ATTR_OS_LINUX
/* Timer Callback Wrapper Find And Fire Function */
static ESIF_INLINE void esif_ccb_timer_cb_wrapper(struct work_struct *work)
{
esif_ccb_timer_t *timer_ptr = container_of(
(struct delayed_work *)work,
esif_ccb_timer_t,
work);
TIMER_DEBUG("%s: timer fired!!!!!\n", ESIF_FUNC);
if (NULL == timer_ptr)
goto exit;
esif_ccb_low_priority_thread_read_lock(&timer_ptr->context_lock);
if (!timer_ptr->exit_flag) {
timer_ptr->function_ptr(timer_ptr->context_ptr);
/* RESET The Timer */
if (timer_ptr->periodic_flag) {
esif_ccb_timer_set_msec(timer_ptr,
timer_ptr->timer_period_msec,
ESIF_TRUE,
timer_ptr->function_ptr,
timer_ptr->context_ptr);
}
}
esif_ccb_low_priority_thread_read_unlock(&timer_ptr->context_lock);
exit:
;
}
#endif /* ESIF_ATTR_OS_LINUX */
#ifdef ESIF_ATTR_OS_WINDOWS
/* Timer Callback Wrapper Find And Fire Function */
#ifdef ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS
static KDEFERRED_ROUTINE esif_ccb_timer_dpc;
static EVT_WDF_WORKITEM esif_ccb_timer_cb_wrapper;
static void esif_ccb_timer_cb_wrapper(
WDFWORKITEM work_item
)
{
esif_ccb_work_item_context_t *work_item_context_ptr = NULL;
esif_ccb_timer_t *timer_ptr = NULL;
esif_ccb_timer_context_t *timer_context_ptr = NULL;
TIMER_DEBUG("%s: timer fired!!!!!\n", ESIF_FUNC);
work_item_context_ptr = esif_ccb_get_work_item_context(work_item);
if(NULL == work_item_context_ptr) {
goto exit;
}
timer_ptr = (esif_ccb_timer_t *)work_item_context_ptr->ptr;
if(NULL == timer_ptr) {
goto exit;
}
timer_context_ptr = &timer_ptr->timer_context;
if (NULL == timer_context_ptr)
goto exit;
esif_ccb_low_priority_thread_read_lock(
&timer_context_ptr->context_lock);
if (!timer_context_ptr->exit_flag) {
timer_context_ptr->function_ptr(timer_context_ptr->context_ptr);
/* RESET The Timer */
if (timer_context_ptr->periodic_flag) {
esif_ccb_timer_set_msec(
timer_ptr,
timer_context_ptr->timer_period_msec,
ESIF_TRUE,
timer_context_ptr->function_ptr,
timer_context_ptr->context_ptr);
}
}
esif_ccb_low_priority_thread_read_unlock(
&timer_context_ptr->context_lock);
exit:
WdfObjectDelete(work_item);
}
static void esif_ccb_timer_dpc (
struct _KDPC *Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2
)
{
NTSTATUS status = STATUS_SUCCESS;
esif_ccb_work_item_context_t *work_item_context_ptr = NULL;
WDF_WORKITEM_CONFIG workItemConfig = {0};
WDF_OBJECT_ATTRIBUTES workItemAttribs = {0};
WDFWORKITEM workItem = NULL;
UNREFERENCED_PARAMETER(Dpc);
UNREFERENCED_PARAMETER(SystemArgument1);
UNREFERENCED_PARAMETER(SystemArgument2);
WDF_WORKITEM_CONFIG_INIT(&workItemConfig, esif_ccb_timer_cb_wrapper);
workItemConfig.AutomaticSerialization = TRUE;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&workItemAttribs,
esif_ccb_work_item_context_t);
workItemAttribs.ParentObject = g_wdf_ipc_queue_handle;
status = WdfWorkItemCreate(&workItemConfig, &workItemAttribs, &workItem);
if (NT_SUCCESS(status)) {
work_item_context_ptr = esif_ccb_get_work_item_context(workItem);
work_item_context_ptr->ptr = DeferredContext;
WdfWorkItemEnqueue(workItem);
}
}
#else /* NOT ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS */
EVT_WDF_TIMER esif_ccb_timer_cb_wrapper;
ESIF_INLINE void esif_ccb_timer_cb_wrapper(WDFTIMER timer)
{
esif_ccb_timer_context_t *timer_context_ptr =
esif_ccb_get_timer_context(timer);
TIMER_DEBUG("%s: timer fired!!!!!\n", ESIF_FUNC);
if (NULL == timer_context_ptr)
goto exit;
esif_ccb_low_priority_thread_read_lock(
&timer_context_ptr->context_lock);
if (!timer_context_ptr->exit_flag) {
timer_context_ptr->function_ptr(timer_context_ptr->context_ptr);
/* RESET The Timer */
if (timer_context_ptr->periodic_flag) {
esif_ccb_timer_set_msec(&timer,
timer_context_ptr->timer_period_msec,
ESIF_TRUE,
timer_context_ptr->function_ptr,
timer_context_ptr->context_ptr);
}
}
esif_ccb_low_priority_thread_read_unlock(
&timer_context_ptr->context_lock);
exit:
(0);
}
#endif /* NOT ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS */
#endif /* ESIF_ATTR_OS_WINDOWS */
/* Timer Initialize */
static ESIF_INLINE
enum esif_rc esif_ccb_timer_init(esif_ccb_timer_t *timer_ptr)
{
enum esif_rc rc = ESIF_E_UNSPECIFIED;
#ifdef ESIF_ATTR_OS_LINUX
TIMER_DEBUG("%s: timer %p\n", ESIF_FUNC, timer_ptr);
INIT_DELAYED_WORK(&timer_ptr->work, NULL);
esif_ccb_low_priority_thread_lock_init(&timer_ptr->context_lock);
timer_ptr->exit_flag = FALSE;
rc = ESIF_OK;
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
#ifdef ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS
esif_ccb_memset(timer_ptr, 0, sizeof(*timer_ptr));
KeInitializeDpc(&timer_ptr->dpc, esif_ccb_timer_dpc, timer_ptr);
KeInitializeTimer(&timer_ptr->timer);
esif_ccb_low_priority_thread_lock_init(
&timer_ptr->timer_context.context_lock);
timer_ptr->timer_context.exit_flag = FALSE;
TIMER_DEBUG("%s: timer %p\n", ESIF_FUNC, timer_ptr);
rc = ESIF_OK;
#else /* NOT ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS */
NTSTATUS status;
WDF_TIMER_CONFIG timer_config = {0};
WDF_OBJECT_ATTRIBUTES timer_attributes = {0};
esif_ccb_timer_context_t *timer_context_ptr = NULL;
TIMER_DEBUG("%s: timer %p\n", ESIF_FUNC, timer_ptr);
WDF_TIMER_CONFIG_INIT(&timer_config, esif_ccb_timer_cb_wrapper);
timer_config.AutomaticSerialization = TRUE;
WDF_OBJECT_ATTRIBUTES_INIT(&timer_attributes);
timer_attributes.ParentObject = g_wdf_ipc_queue_handle;
timer_attributes.ExecutionLevel = WdfExecutionLevelPassive;
WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&timer_attributes,
esif_ccb_timer_context_t);
status = WdfTimerCreate(&timer_config, &timer_attributes, timer_ptr);
TIMER_DEBUG("%s: timer %p status %08x\n", ESIF_FUNC, timer_ptr, status);
if (!NT_SUCCESS(status))
goto exit;
timer_context_ptr = esif_ccb_get_timer_context(*timer_ptr);
if (timer_context_ptr == NULL)
goto exit;
esif_ccb_low_priority_thread_lock_init(&timer_context_ptr->context_lock);
timer_context_ptr->exit_flag = FALSE;
rc = ESIF_OK;
exit:
#endif /* NOT ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS */
#endif /* ESIF_ATTR_OS_WINDOWS */
return rc;
}
/* Timer Set */
static ESIF_INLINE enum esif_rc esif_ccb_timer_set_msec(
esif_ccb_timer_t *timer_ptr,
esif_ccb_time_t timeout,
esif_flags_t periodic,
esif_ccb_timer_cb function_ptr,
void *context_ptr
)
{
enum esif_rc rc = ESIF_E_UNSPECIFIED;
#ifdef ESIF_ATTR_OS_LINUX
u64 x;
u64 y;
u8 result;
#
timer_ptr->periodic_flag = periodic;
timer_ptr->timer_period_msec = timeout;
timer_ptr->function_ptr = function_ptr;
timer_ptr->context_ptr = context_ptr;
TIMER_DEBUG("%s: timer %p timeout %u\n",
ESIF_FUNC,
timer_ptr,
(int)timeout);
PREPARE_DELAYED_WORK(&timer_ptr->work, esif_ccb_timer_cb_wrapper);
/* Keep 32 bit Linux Happy */
x = timeout * HZ;
y = 1000;
do_div(x, y);
result = schedule_delayed_work(&timer_ptr->work, x);
if (ESIF_TRUE == result)
rc = ESIF_OK;
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
#ifdef ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS
esif_ccb_timer_context_t *timer_context_ptr = NULL;
LARGE_INTEGER due_time = {0LL};
u32 tolerable_delay = 0;
TIMER_DEBUG("%s: timer %p timeout %u\n", ESIF_FUNC, timer_ptr, timeout);
if(NULL == timer_ptr) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
timer_context_ptr = &timer_ptr->timer_context;
timer_context_ptr->function_ptr = function_ptr;
timer_context_ptr->context_ptr = context_ptr;
timer_context_ptr->periodic_flag = periodic;
timer_context_ptr->timer_period_msec = timeout;
timer_context_ptr->exit_flag = FALSE;
/*
* Calculate the delay that can be tolerated, with a minimum of at
* least 1 TOLERABLE_DELAY_INCREMENT.
*/
tolerable_delay = (u32) timeout / TOLERABLE_DELAY_DIVISOR;
tolerable_delay = (tolerable_delay / TOLERABLE_DELAY_INCREMENT) + 1;
tolerable_delay *= TOLERABLE_DELAY_INCREMENT;
due_time.QuadPart = (LONGLONG)timeout * -10000;
KeSetCoalescableTimer(&timer_ptr->timer,
due_time,
0,
tolerable_delay,
&timer_ptr->dpc);
rc = ESIF_OK;
exit:
#else /* NOT ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS */
esif_ccb_timer_context_t *timer_context_ptr = NULL;
BOOLEAN status;
TIMER_DEBUG("%s: timer %p timeout %u\n", ESIF_FUNC, timer_ptr, timeout);
if (NULL == timer_ptr) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
/* Set Context */
timer_context_ptr = esif_ccb_get_timer_context(*timer_ptr);
if (NULL != timer_context_ptr) {
timer_context_ptr->timer_period_msec = timeout;
timer_context_ptr->periodic_flag = periodic;
timer_context_ptr->function_ptr = function_ptr;
timer_context_ptr->context_ptr = context_ptr;
timer_context_ptr->exit_flag = FALSE;
}
/* Finally Start Timer */
status = WdfTimerStart(*timer_ptr, (LONG)timeout * -10000);
TIMER_DEBUG("%s: timer %p status %08x\n", ESIF_FUNC, timer_ptr, status);
if (TRUE == status)
rc = ESIF_OK;
exit:
#endif /* NOT ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS */
#endif /* ESIF_ATTR_OS_WINDOWS */
return rc;
}
/* Timer Stop And Destory */
static ESIF_INLINE
enum esif_rc esif_ccb_timer_kill(esif_ccb_timer_t *timer)
{
enum esif_rc rc = ESIF_E_UNSPECIFIED;
#ifdef ESIF_ATTR_OS_LINUX
TIMER_DEBUG("%s: timer %p\n", ESIF_FUNC, timer);
esif_ccb_low_priority_thread_write_lock(&timer->context_lock);
timer->exit_flag = TRUE;
esif_ccb_low_priority_thread_write_unlock(&timer->context_lock);
if (ESIF_TRUE == cancel_delayed_work(&timer->work))
rc = ESIF_OK;
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
#ifdef ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS
esif_ccb_timer_context_t *timer_context_ptr = NULL;
TIMER_DEBUG("%s: timer %p\n", ESIF_FUNC, timer);
if(NULL == timer) {
goto exit;
}
timer_context_ptr = &timer->timer_context;
if (timer_context_ptr != NULL) {
esif_ccb_low_priority_thread_write_lock(
&timer_context_ptr->context_lock);
timer_context_ptr->exit_flag = TRUE;
esif_ccb_low_priority_thread_write_unlock(
&timer_context_ptr->context_lock);
}
KeCancelTimer(&timer->timer);
exit:
rc = ESIF_OK;
#else /* NOT ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS */
esif_ccb_timer_context_t *timer_context_ptr = NULL;
TIMER_DEBUG("%s: timer %p\n", ESIF_FUNC, timer);
timer_context_ptr = esif_ccb_get_timer_context(*timer);
if (timer_context_ptr != NULL) {
esif_ccb_low_priority_thread_write_lock(
&timer_context_ptr->context_lock);
timer_context_ptr->exit_flag = TRUE;
esif_ccb_low_priority_thread_write_unlock(
&timer_context_ptr->context_lock);
}
/* WDF Framework Will Cleanup */
WdfTimerStop(*timer, FALSE);
rc = ESIF_OK;
#endif /* NOT ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS */
#endif /* ESIF_ATTR_OS_WINDOWS */
return rc;
}
#endif /* ESIF_ATTR_KERNEL*/
/******************************************************************************
* USER TIMER
******************************************************************************/
#ifdef ESIF_ATTR_USER
#include "esif.h"
/* OS Agnostic Callback Function */
typedef void (ESIF_CALLCONV *esif_ccb_timer_cb)(const void *context_ptr);
#pragma pack(push, 1)
/* OS Agnostic Timer Context */
typedef struct esif_ccb_timer_ctx {
esif_ccb_timer_cb cb_func; /* Call Back Function */
void *cb_context_ptr; /* Call Back Function Context */
} esif_ccb_timer_ctx_t;
#pragma pack(pop)
#ifdef ESIF_ATTR_OS_LINUX
#include <signal.h>
#pragma pack(push,1)
/* Linux Timer */
typedef struct esif_ccb_timer {
timer_t timer; /* Linux specific timer */
esif_ccb_timer_ctx_t *timer_ctx_ptr; /* OS Agnostic timer context */
esif_ccb_mutex_t context_lock; /* Call back function lock */
} esif_ccb_timer_t;
#pragma pack(pop)
/*
* Each OS Expects its own CALLBACK primitive we use this
* wrapper function to normalize the parameters and and
* ultimately call our func_ptr and func_context originally
* provided to the timer. By example Linux expects a union
* here that contains our timer context poiner which in turn
* contains our function and context for the function.
*/
/* Linux Timer Behavior Note
* Reference : http://man7.org/linux/man-pages/man2/timer_create.2.html
*
* Because of the way POSIX timer callbacks are handled, it is possible
* that the OS may have a pending timer notification for a timer that
* was cancelled, reinitialized, and reset from a user space app. In
* that instance, if you are using the same timer repeatedly you may see
* 2 callbacks for a single timer due to this pending signal issue.
*/
static ESIF_INLINE void esif_ccb_timer_cb_wrapper(
const union sigval sv
)
{
esif_ccb_timer_t* timer_ptr = (esif_ccb_timer_t *)sv.sival_ptr;
ESIF_ASSERT(timer_ptr->timer_ctx_ptr != NULL);
ESIF_ASSERT(timer_ptr->timer_ctx_ptr->cb_func != NULL);
ESIF_ASSERT(timer_ptr->timer_ctx_ptr->cb_context_ptr != NULL);
esif_ccb_mutex_lock(&(timer_ptr->context_lock));
if (NULL != timer_ptr->timer_ctx_ptr &&
NULL != timer_ptr->timer_ctx_ptr->cb_func &&
NULL != timer_ptr->timer_ctx_ptr->cb_context_ptr) {
timer_ptr->timer_ctx_ptr->cb_func(
timer_ptr->timer_ctx_ptr->cb_context_ptr);
}
esif_ccb_mutex_unlock(&(timer_ptr->context_lock));
}
#endif /* ESIF_ATTR_OS_LINUX */
#ifdef ESIF_ATTR_OS_WINDOWS
#include <WinBase.h>
#pragma pack(push,1)
/* Windows Timer */
typedef struct esif_ccb_timer {
HANDLE timer; /* Windows specific timer */
HANDLE timer_wait_handle;
esif_ccb_timer_ctx_t *timer_ctx_ptr; /* OS Agnostic timer context */
} esif_ccb_timer_t;
#pragma pack(pop)
/*
* Each OS Expects its own CALLBACK primitive we use this
* wrapper function to normalize the parameters and and
* ultimately call our func_ptr and func_context originally
* provided to the timer. By example Windows expects two
* parameters of which we only use one. The other one is
* always true.
*/
static ESIF_INLINE void NTAPI esif_ccb_timer_cb_wrapper(
void *context_ptr,
BOOLEAN notUsed
)
{
esif_ccb_timer_ctx_t *timer_ctx_ptr =
(esif_ccb_timer_ctx_t *)context_ptr;
ESIF_ASSERT(timer_ctx_ptr != NULL);
ESIF_ASSERT(timer_ctx_ptr->cb_func != NULL);
ESIF_ASSERT(timer_ctx_ptr->cb_context_ptr != NULL);
UNREFERENCED_PARAMETER(notUsed);
if (NULL != timer_ctx_ptr &&
NULL != timer_ctx_ptr->cb_func &&
NULL != timer_ctx_ptr->cb_context_ptr) {
timer_ctx_ptr->cb_func(timer_ctx_ptr->cb_context_ptr);
}
}
#endif /* ESIF_ATTR_OS_WINDOWS */
static ESIF_INLINE eEsifError esif_ccb_timer_init(
esif_ccb_timer_t *timer_ptr, /* Our Timer */
const esif_ccb_timer_cb function_ptr, /* Callback when timer fires */
void *context_ptr /* Callback context if any */
)
{
eEsifError rc = ESIF_E_UNSPECIFIED;
#ifdef ESIF_ATTR_OS_LINUX
struct sigevent se;
pthread_attr_t attr;
pthread_attr_init(&attr);
#endif
ESIF_ASSERT(timer_ptr != NULL);
ESIF_ASSERT(function_ptr != NULL);
if (NULL == timer_ptr) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
esif_ccb_memset(timer_ptr, 0, sizeof(*timer_ptr));
#ifdef ESIF_ATTR_OS_WINDOWS
timer_ptr->timer = CreateWaitableTimer(NULL, TRUE, NULL);
if (NULL == timer_ptr->timer)
goto exit;
rc = ESIF_OK;
#endif
/* Allocate and setup new context */
timer_ptr->timer_ctx_ptr = (esif_ccb_timer_ctx_t *)
esif_ccb_malloc(sizeof(*timer_ptr->timer_ctx_ptr));
if (NULL == timer_ptr->timer_ctx_ptr) {
rc = ESIF_E_NO_MEMORY;
goto exit;
}
/* Store state for timer set */
timer_ptr->timer_ctx_ptr->cb_func = function_ptr;
timer_ptr->timer_ctx_ptr->cb_context_ptr = context_ptr;
#ifdef ESIF_ATTR_OS_LINUX
/* Initialize the callback lock and exit flag */
esif_ccb_mutex_init(&(timer_ptr->context_lock));
se.sigev_notify = SIGEV_THREAD;
se.sigev_notify_function = esif_ccb_timer_cb_wrapper;
se.sigev_value.sival_ptr = timer_ptr;
se.sigev_notify_attributes = &attr;
if (0 == timer_create(CLOCK_REALTIME, &se,
(timer_t *)&timer_ptr->timer)) {
rc = ESIF_OK;
} else {
esif_ccb_free(timer_ptr->timer_ctx_ptr );
timer_ptr->timer_ctx_ptr = NULL;
}
#endif
exit:
return rc;
}
static ESIF_INLINE eEsifError esif_ccb_timer_set_msec(
esif_ccb_timer_t *timer_ptr, /* Our Timer */
const esif_ccb_time_t timeout /* Timeout in msec */
)
{
eEsifError rc = ESIF_E_UNSPECIFIED;
#ifdef ESIF_ATTR_OS_LINUX
struct itimerspec its;
u64 freq_nanosecs = timeout * 1000 * 1000; /* convert msec to nsec */
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
u32 ret_val = 0;
u32 wait_timeout = (u32) timeout;
#ifdef ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS
u32 tolerable_delay = 0;
LARGE_INTEGER due_time = {0};
#endif
#endif /* ESIF_ATTR_OS_WINDOWS */
ESIF_ASSERT(timer_ptr != NULL);
if (NULL == timer_ptr) {
rc = ESIF_E_NO_MEMORY;
goto exit;
}
#ifdef ESIF_ATTR_OS_WINDOWS
if (NULL == timer_ptr->timer)
goto exit;
if (NULL != timer_ptr->timer_wait_handle) {
UnregisterWaitEx(timer_ptr->timer_wait_handle,
INVALID_HANDLE_VALUE);
timer_ptr->timer_wait_handle = NULL;
}
#ifdef ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS
/*
* Calculate the delay that can be tolerated, with a minimum of at
* least 1 TOLERABLE_DELAY_INCREMENT.
*/
tolerable_delay = (u32) timeout / TOLERABLE_DELAY_DIVISOR;
tolerable_delay = (tolerable_delay / TOLERABLE_DELAY_INCREMENT) + 1;
tolerable_delay *= TOLERABLE_DELAY_INCREMENT;
/*
* For the coalescable timer, we use the timeout of the timer; not
* the timeout of the waiting thread.
*/
wait_timeout = INFINITE;
due_time.QuadPart = -1LL * timeout * DUE_TIME_MS_CONV_FACTOR;
ret_val = SetWaitableTimerEx(timer_ptr->timer,
&due_time,
0,
NULL,
NULL,
NULL,
tolerable_delay);
if (!ret_val)
goto exit;
#endif /* ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS */
ret_val = RegisterWaitForSingleObject(&timer_ptr->timer_wait_handle,
timer_ptr->timer,
esif_ccb_timer_cb_wrapper,
timer_ptr->timer_ctx_ptr,
(u32)wait_timeout,
WT_EXECUTEONLYONCE);
if (!ret_val) {
#ifdef ESIF_FEAT_OPT_USE_COALESCABLE_TIMERS
CancelWaitableTimer(timer_ptr->timer);
#endif
goto exit;
}
rc = ESIF_OK;
#endif /* ESIF_ATTR_OS_WINDOWS */
#ifdef ESIF_ATTR_OS_LINUX
its.it_value.tv_sec = freq_nanosecs / 1000000000;
its.it_value.tv_nsec = freq_nanosecs % 1000000000;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;
if (0 == timer_settime(timer_ptr->timer, 0, &its, NULL))
rc = ESIF_OK;
#endif /* ESIF_ATTR_OS_LINUX */
exit:
return rc;
}
static ESIF_INLINE eEsifError esif_ccb_timer_kill(
esif_ccb_timer_t *timer_ptr /* Our Timer */
)
{
eEsifError rc = ESIF_E_UNSPECIFIED;
if (NULL == timer_ptr)
goto exit;
#ifdef ESIF_ATTR_OS_WINDOWS
if (NULL != timer_ptr->timer_wait_handle) {
UnregisterWaitEx(timer_ptr->timer_wait_handle,
INVALID_HANDLE_VALUE );
timer_ptr->timer_wait_handle = NULL;
}
if (timer_ptr->timer != NULL) {
CloseHandle(timer_ptr->timer);
timer_ptr->timer = NULL;
}
rc = ESIF_OK;
#endif
#ifdef ESIF_ATTR_OS_LINUX
esif_ccb_mutex_lock(&(timer_ptr->context_lock));
if (0 == timer_delete(timer_ptr->timer))
rc = ESIF_OK;
#endif
if (timer_ptr->timer_ctx_ptr != NULL) {
esif_ccb_free(timer_ptr->timer_ctx_ptr);
timer_ptr->timer_ctx_ptr = NULL;
}
#ifdef ESIF_ATTR_OS_LINUX
esif_ccb_mutex_unlock(&(timer_ptr->context_lock));
#endif
exit:
return rc;
}
#endif /* ESIF_ATTR_USER */
#endif /* _ESIF_CCB_TIMER_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,241 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_COMMAND_H_
#define _ESIF_COMMAND_H_
#define ESIF_COMMAND_VERSION 0x1
/* Command Priority */
enum esif_command_priority {
ESIF_COMMAND_PRIORITY_NORMAL = 0,
};
/* Command Priority String */
static ESIF_INLINE esif_string esif_command_priority_str(
enum esif_command_priority priority)
{
#define CREATE_COMMAND_PRIORITY(cp, str) case cp: str = (esif_string) #cp; break;
esif_string str = (esif_string)ESIF_NOT_AVAILABLE;
switch (priority) {
CREATE_COMMAND_PRIORITY(ESIF_COMMAND_PRIORITY_NORMAL, str);
}
return str;
}
/* Command Types */
enum esif_command_type {
ESIF_COMMAND_TYPE_GET_DEBUG_MODULES = 0,
ESIF_COMMAND_TYPE_SET_DEBUG_MODULES,
ESIF_COMMAND_TYPE_GET_DEBUG_MODULE_LEVEL,
ESIF_COMMAND_TYPE_SET_DEBUG_MODULE_LEVEL,
ESIF_COMMAND_TYPE_GET_KERNEL_INFO,
ESIF_COMMAND_TYPE_GET_PARTICIPANTS,
ESIF_COMMAND_TYPE_GET_PARTICIPANT_DETAIL,
ESIF_COMMAND_TYPE_GET_MEMORY_STATS,
};
static ESIF_INLINE esif_string esif_command_type_str(
enum esif_command_type type)
{
#define CREATE_COMMAND_TYPE(ct, str) case ct: str = (esif_string) #ct; break;
esif_string str = (esif_string)ESIF_NOT_AVAILABLE;
switch (type) {
CREATE_COMMAND_TYPE(ESIF_COMMAND_TYPE_GET_DEBUG_MODULE_LEVEL, str)
CREATE_COMMAND_TYPE(ESIF_COMMAND_TYPE_GET_DEBUG_MODULES, str)
CREATE_COMMAND_TYPE(ESIF_COMMAND_TYPE_SET_DEBUG_MODULE_LEVEL, str)
CREATE_COMMAND_TYPE(ESIF_COMMAND_TYPE_SET_DEBUG_MODULES, str)
CREATE_COMMAND_TYPE(ESIF_COMMAND_TYPE_GET_KERNEL_INFO, str)
CREATE_COMMAND_TYPE(ESIF_COMMAND_TYPE_GET_PARTICIPANTS, str)
CREATE_COMMAND_TYPE(ESIF_COMMAND_TYPE_GET_PARTICIPANT_DETAIL, str)
CREATE_COMMAND_TYPE(ESIF_COMMAND_TYPE_GET_MEMORY_STATS, str)
}
return str;
}
/* Packaed Command Data structures */
#pragma pack(push, 1)
struct esif_command_get_kernel_info {
char ver_str[ESIF_NAME_LEN];
};
struct esif_command_debug_modules {
u32 modules;
};
struct esif_command_get_debug_module_level {
u32 modules;
u32 levels[32];
u32 tracelevel;
};
struct esif_command_set_debug_module_level {
u32 module;
u32 level;
};
struct esif_command_get_participant {
u32 id;
u32 version;
u32 state;
u32 bus_enum;
char name[ESIF_NAME_LEN];
char desc[ESIF_DESC_LEN];
u8 class_guid[ESIF_GUID_LEN]; /* Class GUID */
char dsp_code[12 + 1];
u8 dsp_ver_major;
u8 dsp_ver_minor;
};
struct esif_command_get_participants {
u32 count;
struct esif_command_get_participant participant_info[20];
};
struct esif_command_get_participant_detail {
/* Participant Info */
u32 id; /* Participant ID */
u8 version; /* Participant Version */
u8 enumerator; /* Participant Enumerator */
char name[ESIF_NAME_LEN]; /* Participant Display Name */
char desc[ESIF_DESC_LEN]; /* Participant Description */
char driver_name[ESIF_NAME_LEN]; /* Participant Driver Name */
char device_name[ESIF_NAME_LEN]; /* Participant Device Name */
char device_path[ESIF_PATH_LEN]; /* Participant Device Path */
u8 class_guid[ESIF_GUID_LEN]; /* Participant Class GUID */
u32 flags; /* Participant Flags If Any */
u32 capability; /* Participant Static Capability*/
/* ACPI */
char acpi_device[ESIF_SCOPE_LEN]; /* Device e.g. INT3400 */
char acpi_scope[ESIF_SCOPE_LEN];/* Scope/REGEX e.g. \_SB.PCI0.TPCH */
char acpi_uid[ESIF_ACPI_UID_LEN]; /* Unique ID If Any */
u32 acpi_type; /* Participant Type If Any */
/* PCI */
u16 pci_vendor; /* PCI Vendor For PCI Devices */
u16 pci_device; /* PCE Device For PCI Devices */
u8 pci_bus; /* Bus Device Was Enumerated On */
u8 pci_bus_device; /* Device Number On Bus */
u8 pci_function; /* PCI Function Of Device */
u8 pci_revision; /* PCI Hardware Revision */
u8 pci_class; /* PCI Hardware Class */
u8 pci_sub_class; /* PCI Hardware Sub Class */
u8 pci_prog_if; /* PCI Hardware Iface */
/* LP */
u32 state;
u32 timer_period;
/* DSP */
u32 have_dsp;
char dsp_code[12 + 1];
u8 dsp_ver_major;
u8 dsp_ver_minor;
/* CPC */
u32 have_cpc;
u8 cpc_version;
u32 cpc_signature;
u32 cpc_size;
u32 cpc_primitive_count;
};
struct esif_mempool_stat {
u32 pool_tag;
u32 object_size;
char name[ESIF_NAME_LEN];
u32 alloc_count;
u32 free_count;
};
struct esif_memtype_stat {
u32 pool_tag;
char name[ESIF_NAME_LEN];
u32 alloc_count;
u32 free_count;
};
struct esif_command_get_memory_stats {
struct esif_mempool_stat mempool_stat[ESIF_MEMPOOL_TYPE_MAX];
struct esif_memtype_stat memtype_stat[ESIF_MEMTYPE_TYPE_MAX];
struct esif_memory_stats stats;
};
#pragma pack(pop)
#ifdef __cplusplus
extern "C" {
#endif
struct esif_ipc *esif_execute_ipc_command (struct esif_ipc *ipc_ptr);
enum esif_rc esif_command_init (void);
void esif_command_exit (void);
#ifdef __cplusplus
}
#endif
#endif /* _ESIF_COMMAND_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,194 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_CPC_H_
#define _ESIF_CPC_H_
#include "esif.h"
#include "esif_primitive.h"
#include "esif_event.h"
/*--- CPC ---*/
/* Must Be Aligned With DSP's dsp_info.h: cpc_descriptor{} */
struct esif_cpc_descriptor {
u32 signature; /* %CPC */
u8 version; /* Version Of Data Structure */
esif_flags_t flags; /* Flags If Any */
esif_flags_t capability; /* Capability */
};
/* Must Be Aligned With DSP's dsp_info.h short_dsp_desriptor{} */
struct esif_cpc_header {
struct esif_cpc_descriptor cpc; /* CPC Or Other */
u8 version; /* Version Of Data Structure */
char code[12 + 1]; /* Code Name For DSP */
u8 ver_major; /* Content Major Version 1.x */
u8 ver_minor; /* Content Minor Version x.1 */
esif_flags_t flags; /* Flags If Any */
};
/* Must Be Aligned With DSP's cpc.h: cpc{} */
struct esif_lp_cpc {
u32 size;
struct esif_cpc_header header;
u32 number_of_algorithms;
u32 number_of_basic_primitives;
u32 number_of_domains;
u32 number_of_events;
/* primitives are laid down here */
/* algorithms come after the primitives */
/* domains come after algorithms */
/* events are laid after domain */
};
/* CPC Primitive */
/* Must Be Aligned With DSP's basic_primitive.h: basic_primitive{} */
struct esif_cpc_primitive {
u32 size;
struct esif_primitive_tuple tuple;
enum esif_primitive_opcode operation; /* ESIF_PRIMITIVE_OP_GET */
u32 number_of_actions;
/* actions are laid down here */
};
/* CPC Action */
/* Must Be Aligned With DSP's basic_action.h: basic_action{} */
struct esif_cpc_action {
enum esif_action_type type; /* Example:
*ESIF_ACTION_ACPI */
u8 num_valid_params; /* Number Of Valid Parameters */
u8 param_valid[5]; /* Array Of Valid Parameters */
u32 param[5]; /* _TMP, NULL, NULL, NULL, NULL */
};
/* CPC Algorithm */
/* Must Be Aligned With DSP's algorithm.h: algorithm{} */
struct esif_cpc_algorithm {
enum esif_action_type action_type;
u32 temp_xform;
u32 tempC1;
u32 tempC2;
u32 power_xform;
u32 time_xform;
u32 size;
};
#define MAX_NAME_STRING_LENGTH 32
#define MAX_DOMAIN_TYPE_STRING_LENGTH ESIF_GUID_LEN
#define MAX_DESCRIPTION_STRING_LENGTH 128
/* CPC Event */
/* Must Be Aligned With DSP's event.h: event{} */
/* Maps a Event_ID to ESIF Event ENUM OR UUID Based */
struct esif_cpc_event {
char name[MAX_NAME_STRING_LENGTH];
u8 event_key[ESIF_GUID_LEN]; /* Event ID */
enum esif_event_type esif_event; /* ESIF Event */
u8 event_guid[ESIF_GUID_LEN]; /* Event GUID */
enum esif_event_group esif_group; /* ESIF Event Group */
enum esif_data_type esif_group_data_type;
};
struct domain_descriptor {
char name[MAX_NAME_STRING_LENGTH];
char description[MAX_DESCRIPTION_STRING_LENGTH];
u16 qualifier;
u8 guid[MAX_DOMAIN_TYPE_STRING_LENGTH];
u32 priority;
enum esif_domain_type domainType;
};
struct capability {
esif_flags_t capability_flags;
u8 number_of_capability_flags;
u8 reserved[3];
u8 capability_mask[32];
};
struct domain {
u32 size;
struct domain_descriptor descriptor;
u32 number_of_primitives;
struct capability capability_for_domain;
};
/* Unpack CPC Data Into DSP */
struct esif_lp_dsp;
#ifdef __cplusplus
extern "C" {
#endif
enum esif_rc esif_cpc_unpack(struct esif_lp_dsp *dsp_ptr,
const struct esif_data *cpc_ptr);
/* Free CPC Data From DSP */
void esif_cpc_free(struct esif_lp_dsp *dsp_ptr);
/* Init / Exit */
enum esif_rc esif_cpc_init(void);
void esif_cpc_exit(void);
#ifdef __cplusplus
}
#endif
#include "esif_dsp.h"
#endif /* _ESIF_CPC_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,210 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_DATA_H_
#define _ESIF_DATA_H_
/* include enum esif_data_type, and lookup */
/* #ifdef ESIF_ATTR_USER */
#include "esif.h"
/* #endif */
#include "autogen.h"
/*
** User Decleration
*/
/*
** Agnostic Decleration
*/
/* Have ESIF Allocate Buffer */
#define ESIF_DATA_ALLOCATE 0xFFFFFFFF
#pragma pack(push,1)
/* All ESIF Data Buffers Are Of This Form */
struct esif_data {
enum esif_data_type type; /* Buffer Type */
void *buf_ptr; /* Buffer */
u32 buf_len; /* Sizeof Allocated Buffer By Memory Allocator
**/
u32 data_len; /* Sizeof Actual Data Contents */
};
/* Cooling Mode Policy */
struct esif_data_complex_scp {
u32 cooling_mode;
u32 acoustic_limit;
u32 power_limit;
};
/* Thermal Shutdown Event */
struct esif_data_complex_shutdown {
u32 temperature;
u32 tripPointTemperature;
};
/* Operating System Capabilities */
struct esif_data_complex_osc {
esif_guid_t guid;
u32 revision;
u32 count;
u32 status; /* Required */
u32 capabilities; /* Always Used By DPTF */
};
/* GUID Pair */
struct esif_data_complex_guid_pair {
esif_guid_t guid1; /* Example SUB_GROUP */
esif_guid_t guid2; /* Example Power Setting */
};
#define ESIF_TABLE_NO_REVISION 0xffff
struct esif_table_hdr {
u8 revision;
u16 rows;
u16 cols;
};
/* Variant */
/* Binary data shall be identical to what upper framework sees */
/* Pack so we end up with exactly 12 bytes always */
union esif_data_variant {
enum esif_data_type type;
/* Integer */
struct {
enum esif_data_type type; /* 4 Bytes For Most Compilers */
u64 value; /* 8 Byte Integer */
}
integer;
/* ASCII String NULL Included In Length */
struct {
enum esif_data_type type; /* 4 Bytes For Most Compilers
* */
u32 length; /* 4 Bytes */
u32 reserved; /* Align To 12 Bytes */
}
string;
/* String Data Here */
};
#pragma pack(pop)
#ifdef __cplusplus
extern "C" {
#endif
/* Allocate */
struct esif_data *esif_data_alloc(enum esif_data_type type, u32 data_len);
void esif_data_free(struct esif_data *data_ptr);
/* Init */
enum esif_rc esif_data_init(void);
void esif_data_exit(void);
#ifdef __cplusplus
}
#endif
#ifdef ESIF_ATTR_USER
typedef struct esif_data EsifData, *EsifDataPtr, **EsifDataPtrLocation;
/*
* ESIF Data is used to marshall most data between ESIF and the
* application it contains. ESIF data uses the populare TLV
* format for describing the data. It can be used to request
* specific data from an object or to identify the data type that
* is returned. While a simple structure it is very helpful. Here
* are a set of convinience initializers to make working with this
* structure easier.
*/
#define ESIF_DATA(var, type, buf_ptr, buf_len) \
EsifData var = { \
ESIF_ELEMENT(.type) type, \
ESIF_ELEMENT(.buf_ptr) buf_ptr, \
ESIF_ELEMENT(.buf_len) buf_len \
}
#define ESIF_DATA_VOID(var) \
EsifData var = { \
ESIF_ELEMENT(.type) ESIF_DATA_VOID, \
ESIF_ELEMENT(.buf_ptr) NULL, \
ESIF_ELEMENT(.buf_len) 0 \
}
#define ESIF_DATA_AUTO(var) \
EsifData var = { \
ESIF_ELEMENT(.type) ESIF_DATA_AUTO, \
ESIF_ELEMENT(.buf_ptr) ESIF_DATA_ALLOCATE, \
ESIF_ELEMENT(.buf_len) 0 \
}
#endif /* ESIF_ATTR_USER */
#endif /* _ESIF_DATA_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,453 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif.h"
#include "esif_debug.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified
* against Windows SDK/DDK included headers which we have no control over.
*
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
#ifdef ESIF_ATTR_KERNEL
/* Debug Data */
u32 g_esif_trace_level = ESIF_TRACELEVEL_ERROR;
u32 g_esif_module_mask = 0xFFFFFFFF;
u32 g_esif_module_category_mask[ESIF_DEBUG_MOD_MAX];
/* Init Debug Modules */
void esif_debug_init_module_categories ()
{
int i;
for (i = 0; i < ESIF_DEBUG_MOD_MAX; i++)
g_esif_module_category_mask[i] = ESIF_TRACE_CATEGORY_DEFAULT;
}
/* Set Debug Modules */
void esif_debug_set_modules (u32 module_mask)
{
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ELF,
ESIF_TRACE_CATEGORY_DEBUG,
"%s: setting debug modules: 0x%08X\n",
ESIF_FUNC,
module_mask);
g_esif_module_mask = module_mask;
}
/* Get Debug Modules */
void esif_debug_get_modules (u32 *module_mask_ptr)
{
*module_mask_ptr = g_esif_module_mask;
}
/* Set Module Level */
void esif_debug_set_module_category (
u32 module,
u32 module_level_mask
)
{
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ELF,
ESIF_TRACE_CATEGORY_DEBUG,
"%s: %s(%d) debug level: 0x%08X\n",
ESIF_FUNC,
esif_debug_mod_str((enum esif_debug_mod)module),
module,
module_level_mask);
if (module < ESIF_DEBUG_MOD_MAX)
g_esif_module_category_mask[module] = module_level_mask;
else if (module == (u32)(-1) && module_level_mask <= ESIF_TRACELEVEL_DEBUG)
g_esif_trace_level = module_level_mask;
}
/* Get Module Level */
void esif_debug_get_module_category (
u32 module,
u32 *module_level_mask_ptr
)
{
if (module < ESIF_DEBUG_MOD_MAX)
*module_level_mask_ptr = g_esif_module_category_mask[module];
}
#else /* USER */
#include "esif_uf_log.h"
#ifdef ESIF_ATTR_OS_WINDOWS
#endif
#ifdef ESIF_ATTR_OS_LINUX
# ifdef ESIF_ATTR_OS_ANDROID
# include <android/log.h>
# define IDENT "DPTF"
# define ESIF_PRIORITY_FATAL ANDROID_LOG_FATAL
# define ESIF_PRIORITY_ERROR ANDROID_LOG_ERROR
# define ESIF_PRIORITY_WARNING ANDROID_LOG_WARN
# define ESIF_PRIORITY_INFO ANDROID_LOG_INFO
# define ESIF_PRIORITY_DEBUG ANDROID_LOG_DEBUG
# else
# include <syslog.h>
# define IDENT "DPTF"
# define OPTION LOG_PID
# define FACILITY LOG_DAEMON
# define ESIF_PRIORITY_FATAL LOG_EMERG
# define ESIF_PRIORITY_ERROR LOG_ERR
# define ESIF_PRIORITY_WARNING LOG_WARNING
# define ESIF_PRIORITY_INFO LOG_INFO
# define ESIF_PRIORITY_DEBUG LOG_DEBUG
# endif
#endif
#define TRACEON(module) ((esif_tracemask_t)1 << (module))
#define TRACEOFF(module) ((esif_tracemask_t)0)
// Default Trace Module BitMask for DEBUG Messages
// NOTE: Modules without a "#define ESIF_TRACE_ID" use DEFAULT option
#define ESIF_TRACEMASK_DEBUG ( \
TRACEOFF(ESIF_TRACEMODULE_DEFAULT) | \
TRACEON (ESIF_TRACEMODULE_DPTF) | \
TRACEOFF(ESIF_TRACEMODULE_CCB) | \
TRACEON (ESIF_TRACEMODULE_SHELL) | \
TRACEOFF(ESIF_TRACEMODULE_UF) | \
TRACEON (ESIF_TRACEMODULE_ACTION) | \
TRACEON (ESIF_TRACEMODULE_APP) | \
TRACEON (ESIF_TRACEMODULE_CONJURE) | \
TRACEOFF(ESIF_TRACEMODULE_DSP) | \
TRACEOFF(ESIF_TRACEMODULE_EVENT) | \
TRACEOFF(ESIF_TRACEMODULE_IPC) | \
TRACEOFF(ESIF_TRACEMODULE_PARTICIPANT) | \
TRACEOFF(ESIF_TRACEMODULE_PRIMITIVE) | \
TRACEON (ESIF_TRACEMODULE_SERVICE) | \
TRACEON (ESIF_TRACEMODULE_TEST) | \
TRACEOFF(ESIF_TRACEMODULE_DATAVAULT) | \
TRACEOFF(ESIF_TRACEMODULE_EQL) | \
TRACEON (ESIF_TRACEMODULE_WEBSERVER) | \
/* windows specific */ \
TRACEOFF(ESIF_TRACEMODULE_WINDOWS) | \
TRACEON (ESIF_TRACEMODULE_ACTWIRELESS) | \
TRACEOFF(ESIF_TRACEMODULE_UMDF) | \
TRACEOFF(0) )
int g_traceLevel = ESIF_TRACELEVEL_DEFAULT;
struct esif_tracelevel_s g_traceinfo[] = {
{"FATAL", ESIF_TRACELEVEL_FATAL, ESIF_TRACEMASK_ALL, ESIF_TRACEROUTE_EVENTLOG},
{"ERROR", ESIF_TRACELEVEL_ERROR, ESIF_TRACEMASK_ALL, ESIF_TRACEROUTE_EVENTLOG},
{"WARNING", ESIF_TRACELEVEL_WARN, ESIF_TRACEMASK_ALL, ESIF_TRACEROUTE_EVENTLOG},
{"INFO", ESIF_TRACELEVEL_INFO, ESIF_TRACEMASK_ALL, ESIF_TRACEROUTE_EVENTLOG},
{"DEBUG", ESIF_TRACELEVEL_DEBUG, ESIF_TRACEMASK_ALL, ESIF_TRACEROUTE_DEBUGGER},
};
#define ESIF_TRACELEVEL_MAX ((sizeof(g_traceinfo) / sizeof(struct esif_tracelevel_s)) - 1)
int g_traceLevel_max = ESIF_TRACELEVEL_MAX;
#define DETAILED_TRACELEVEL ESIF_TRACELEVEL_FATAL /* All Trace Levels */
const struct EsifTraceModuleList_s {
enum esif_tracemodule id;
const char *str;
} g_EsifTraceModuleList[] = {
ENUM_TRACEMODULE(ENUMLIST)
{(enum esif_tracemodule)0}
};
const enum esif_tracemodule EsifTraceModule_FromString(const char *name)
{
int j;
for (j=0; g_EsifTraceModuleList[j].str; j++) {
if (esif_ccb_stricmp(name, g_EsifTraceModuleList[j].str)==0 || // ESIF_TRACEMODULE_XXXX
esif_ccb_stricmp(name, g_EsifTraceModuleList[j].str+17)==0) // XXXX
return g_EsifTraceModuleList[j].id;
}
return (enum esif_tracemodule)0;
}
#define ENUMSWITCHSTR(ENUM) case ENUM: str = #ENUM; break;
#define ENUMSWITCHSTR_VAL(ENUM) ENUMSWITCHSTR(ENUM)
const char *EsifTraceModule_ToString(enum esif_tracemodule val)
{
const char *str = NULL;
switch (val) {
ENUM_TRACEMODULE(ENUMSWITCHSTR)
default:
break;
}
if (str)
str += 17; // Truncate "ESIF_TRACEMODULE_"
return str;
}
int EsifTraceMessage(
esif_tracemask_t module,
int level,
const char *func,
const char *file,
int line,
const char *msg,
...)
{
int rc=0;
char *appname = "";
char *fmtDetail= "%s%s:[%s@%s#%d]: ";
char *fmtInfo = "%s%s: ";
const char *sep=NULL;
size_t fmtlen=esif_ccb_strlen(msg, 0x7FFFFFFF);
int detailed_message = (level >= DETAILED_TRACELEVEL ? ESIF_TRUE : ESIF_FALSE);
va_list args;
UNREFERENCED_PARAMETER(module);
level = esif_ccb_min(level, ESIF_TRACELEVEL_MAX);
if ((sep = strrchr(file, *ESIF_PATH_SEP)) != NULL)
file = sep+1;
// Do not function/file/line number information for app interface messages logged from EsifSvcWriteLog
if (esif_ccb_strcmp(func, "EsifSvcWriteLog") == 0) {
detailed_message = ESIF_FALSE;
}
if (g_traceinfo[level].routes & ESIF_TRACEROUTE_CONSOLE) {
if (detailed_message)
rc = CMD_CONSOLE(fmtDetail, appname, g_traceinfo[level].label, func, file, line);
else
rc = CMD_CONSOLE(fmtInfo, appname, g_traceinfo[level].label);
va_start(args, msg);
rc += EsifConsole_WriteConsole(msg, args);
va_end(args);
if (fmtlen && msg[fmtlen-1]!='\n')
CMD_CONSOLE("\n");
}
if (g_traceinfo[level].routes & ESIF_TRACEROUTE_LOGFILE && EsifLogFile_IsOpen(ESIF_LOG_TRACE)) {
time_t now=0;
char timestamp[MAX_CTIME_LEN]={0};
time(&now);
esif_ccb_ctime(timestamp, sizeof(timestamp), &now);
timestamp[20] = 0; // truncate year
if (detailed_message)
rc = EsifLogFile_Write(ESIF_LOG_TRACE, fmtDetail, timestamp+4, g_traceinfo[level].label, func, file, line);
else
rc = EsifLogFile_Write(ESIF_LOG_TRACE, fmtInfo, timestamp+4, g_traceinfo[level].label);
va_start(args, msg);
rc += EsifLogFile_WriteArgs(ESIF_LOG_TRACE, msg, args);
va_end(args);
if (fmtlen && msg[fmtlen-1]!='\n')
EsifLogFile_Write(ESIF_LOG_TRACE, "\n");
}
#ifdef ESIF_ATTR_OS_WINDOWS
if (g_traceinfo[level].routes & (ESIF_TRACEROUTE_DEBUGGER)) {
size_t msglen=0;
char *buffer=0;
int offset=0;
va_start(args, msg);
msglen = esif_ccb_vscprintf(msg, args) + esif_ccb_strlen(g_traceinfo[level].label, MAX_PATH) + esif_ccb_strlen(appname, MAX_PATH) + esif_ccb_strlen(func, MAX_PATH) + esif_ccb_strlen(file, MAX_PATH) + 10;
va_end(args);
msglen += (detailed_message ? esif_ccb_strlen(fmtDetail, MAX_PATH) : esif_ccb_strlen(fmtInfo, MAX_PATH));
buffer = (char *)esif_ccb_malloc(msglen);
if (NULL != buffer) {
if (detailed_message)
rc = esif_ccb_sprintf(msglen, buffer, fmtDetail, appname, g_traceinfo[level].label, func, file, line);
else
rc = esif_ccb_sprintf(msglen, buffer, fmtInfo, appname, g_traceinfo[level].label);
offset = rc;
va_start(args, msg);
rc += esif_ccb_vsprintf(msglen-offset, buffer+offset, msg, args);
va_end(args);
if (rc && buffer[rc-1]!='\n')
esif_ccb_strcat(buffer, "\n", msglen);
OutputDebugStringA(buffer);
esif_ccb_free(buffer);
}
}
if (g_traceinfo[level].routes & (ESIF_TRACEROUTE_EVENTLOG)) {
size_t msglen=0;
char *buffer=0;
int offset=0;
int backset=0;
WORD eventType;
appname = "";
fmtInfo = "%sESIF(%s) TYPE: %s\n\n";
fmtDetail= "%sESIF(%s) TYPE: %s FUNC: %s FILE: %s LINE: %d\n\n";
backset = 0;
va_start(args, msg);
msglen = esif_ccb_vscprintf(msg,args) + esif_ccb_strlen(g_traceinfo[level].label, MAX_PATH) + esif_ccb_strlen(appname, MAX_PATH) + esif_ccb_strlen(func, MAX_PATH) + esif_ccb_strlen(file, MAX_PATH) + 20;
va_end(args);
msglen += (detailed_message ? esif_ccb_strlen(fmtDetail, MAX_PATH) : esif_ccb_strlen(fmtInfo, MAX_PATH));
buffer = (char *)esif_ccb_malloc(msglen);
if (NULL != buffer) {
if (detailed_message)
rc = esif_ccb_sprintf(msglen, buffer, fmtDetail, appname, ESIF_UF_VERSION, g_traceinfo[level].label, func, file, line);
else
rc = esif_ccb_sprintf(msglen, buffer, fmtInfo, appname, ESIF_UF_VERSION, g_traceinfo[level].label);
if (backset && backset < rc)
buffer[rc-backset-1] = 0;
offset = rc-backset;
va_start(args, msg);
rc += esif_ccb_vsprintf(msglen-(offset+backset), buffer+offset+backset, msg, args);
va_end(args);
if (rc && buffer[rc-1]=='\n')
buffer[--rc] = 0;
switch (g_traceinfo[level].level) {
case ESIF_TRACELEVEL_FATAL:
case ESIF_TRACELEVEL_ERROR:
eventType = EVENTLOG_ERROR_TYPE;
break;
case ESIF_TRACELEVEL_WARN:
eventType = EVENTLOG_WARNING_TYPE;
break;
case ESIF_TRACELEVEL_INFO:
case ESIF_TRACELEVEL_DEBUG:
default:
eventType = EVENTLOG_INFORMATION_TYPE;
break;
}
report_event_to_event_log(CATEGORY_GENERAL, eventType, buffer);
esif_ccb_free(buffer);
}
}
#endif
#ifdef ESIF_ATTR_OS_LINUX
if (g_traceinfo[level].routes & (ESIF_TRACEROUTE_EVENTLOG|ESIF_TRACEROUTE_DEBUGGER)) {
size_t msglen=0;
char *buffer=0;
int offset=0;
int priority;
fmtDetail= "%s:[%s@%s#%d]: ";
fmtInfo = "%s: ";
va_start(args, msg);
msglen = esif_ccb_vscprintf(msg,args) + esif_ccb_strlen(g_traceinfo[level].label, MAX_PATH) + esif_ccb_strlen(func, MAX_PATH) + esif_ccb_strlen(file, MAX_PATH) + 10;
va_end(args);
msglen += (detailed_message ? esif_ccb_strlen(fmtDetail, MAX_PATH) : esif_ccb_strlen(fmtInfo, MAX_PATH));
buffer = (char *)esif_ccb_malloc(msglen);
if (NULL != buffer) {
if (detailed_message)
rc = esif_ccb_sprintf(msglen, buffer, fmtDetail, g_traceinfo[level].label, func, file, line);
else
rc = esif_ccb_sprintf(msglen, buffer, fmtInfo, g_traceinfo[level].label);
offset = rc;
va_start(args, msg);
rc += esif_ccb_vsprintf(msglen-offset, buffer+offset, msg, args);
va_end(args);
if (rc && buffer[rc-1]=='\n')
buffer[--rc] = 0;
switch (g_traceinfo[level].level) {
case ESIF_TRACELEVEL_FATAL:
priority = ESIF_PRIORITY_FATAL;
break;
case ESIF_TRACELEVEL_ERROR:
priority = ESIF_PRIORITY_ERROR;
break;
case ESIF_TRACELEVEL_WARN:
priority = ESIF_PRIORITY_WARNING;
break;
case ESIF_TRACELEVEL_INFO:
priority = ESIF_PRIORITY_INFO;
break;
case ESIF_TRACELEVEL_DEBUG:
default:
priority = ESIF_PRIORITY_DEBUG;
break;
}
#ifdef ESIF_ATTR_OS_ANDROID
__android_log_write(priority, IDENT, buffer);
#else
openlog(IDENT, OPTION, FACILITY);
syslog(priority, "%s", buffer);
closelog();
#endif
esif_ccb_free(buffer);
}
}
#endif
return rc;
}
#endif /* NOT ESIF_ATTR_KERNEL */
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,537 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_DEBUG_H_
#define _ESIF_DEBUG_H_
#include "esif.h"
#define NO_ESIF_DEBUG(fmt, ...) ESIF_TRACENULL
#define ESIF_DEBUG(fmt, ...) ESIF_TRACE_DEBUG(fmt, ##__VA_ARGS__)
/*
* Kernel Module Types:
* The following enumeration specifies the index of a given LF module into
* an array of debug masks for each modue type. Each LF C file should
* contain a ESIF_DEBUG_MODULE item defined as one of the enum items.
* Note: The Kernel-Mode Debug Modules definitions are available in User Mode
* so that the kernel-mode debug level can be decoded in user-mode.
*/
enum esif_debug_mod {
ESIF_DEBUG_MOD_ACTION_VAR = 0, /* Action Variable */
ESIF_DEBUG_MOD_ACTION_CONST = 1, /* Action Constant */
ESIF_DEBUG_MOD_ACTION_MSR = 2, /* Action MSR */
ESIF_DEBUG_MOD_ACTION_MMIO = 3, /* Action MMIO */
ESIF_DEBUG_MOD_ACTION_ACPI = 4, /* Action ACPI */
ESIF_DEBUG_MOD_IPC = 5, /* IPC */
ESIF_DEBUG_MOD_COMMAND = 6, /* Command Pre DSP */
ESIF_DEBUG_MOD_PRIMITIVE = 7, /* Primitive Requires DSP */
ESIF_DEBUG_MOD_ACTION = 8, /* Primitive Requires DSP */
ESIF_DEBUG_MOD_CPC = 9, /* Loads DSP */
ESIF_DEBUG_MOD_DATA = 10, /* Data Operations */
ESIF_DEBUG_MOD_DSP = 11, /* DSP Operations */
ESIF_DEBUG_MOD_EVENT = 12, /* Event Processing */
ESIF_DEBUG_MOD_ELF = 13, /* ESIF Lower Framework */
ESIF_DEBUG_MOD_PMG = 14, /* Package Manager */
ESIF_DEBUG_MOD_QUEUE = 15, /* Queue Manager */
ESIF_DEBUG_MOD_HASH = 16, /* Hash Tables */
ESIF_DEBUG_MOD_ACTION_SYSTEMIO = 17, /* Action SYSTEM IO */
ESIF_DEBUG_MOD_ACTION_CODE = 18, /* Action Code */
ESIF_DEBUG_MOD_POL = 19, /* Polling Code */
ESIF_DEBUG_MOD_ACTION_MBI = 20, /* Action MBI (ATOM) */
ESIF_DEBUG_MOD_GENERAL = 21, /* Non-Specific tracing */
ESIF_DEBUG_MOD_WINDOWS = 22, /* Windows-Specific */
ESIF_DEBUG_MOD_LINUX = 23, /* Linux-Specific */
ESIF_DEBUG_MOD_MAX
};
static ESIF_INLINE char *esif_debug_mod_str(enum esif_debug_mod mod)
{
#define ESIF_CREATE_MOD(mod, ab, str) case mod: str = (esif_string) #ab; break;
esif_string str = (esif_string)ESIF_NOT_AVAILABLE;
switch (mod) {
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_ACTION_VAR, VAR, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_ACTION_CONST, CON, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_ACTION_MSR, MSR, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_ACTION_MMIO, MMI, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_ACTION_ACPI, ACP, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_IPC, IPC, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_COMMAND, CMD, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_PRIMITIVE, PRI, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_ACTION, ACT, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_CPC, CPC, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_DATA, DAT, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_DSP, DSP, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_EVENT, EVE, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_ELF, ELF, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_PMG, PMG, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_QUEUE, QUE, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_HASH, HSH, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_ACTION_SYSTEMIO, SIO, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_ACTION_CODE, COD, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_POL, POL, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_ACTION_MBI, MBI, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_GENERAL, GNL, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_WINDOWS, WND, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_LINUX, LNX, str)
ESIF_CREATE_MOD(ESIF_DEBUG_MOD_MAX, MAX, str)
}
return str;
}
/*
* Kernel Memory Statistics
*/
#pragma pack(push,1)
struct esif_memory_stats {
u32 allocs; /* Total number of allocations */
u32 frees; /* Total number of frees */
u32 memPoolAllocs; /* Total number of allocations */
u32 memPoolFrees; /* Total number of frees */
u32 memPoolObjAllocs; /* Total number of allocations */
u32 memPoolObjFrees; /* Total number of frees */
u32 memTypeAllocs; /* Total number of allocations */
u32 memTypeFrees; /* Total number of frees */
u32 memTypeObjAllocs; /* Total number of allocations */
u32 memTypeObjFrees; /* Total number of frees */
};
#pragma pack(pop)
/* ESIF Trace Levels. These correspond to eLogLevel enum type */
#define ESIF_TRACELEVEL_FATAL 0
#define ESIF_TRACELEVEL_ERROR 1
#define ESIF_TRACELEVEL_WARN 2
#define ESIF_TRACELEVEL_INFO 3
#define ESIF_TRACELEVEL_DEBUG 4
#ifdef ESIF_ATTR_KERNEL
/*
* The kernel debug facilities allow the user to specify debug output from
* particular modules and categories specific to a given module. The categories
* are enabled by a bitmask associated each module. Several categories are
* predefined to specify "levels" for universal trace macros. (These are in
* the upper bits of the category mask. Module specific macros should use the
* lower bits.)
* For general items, the universal macros may be used:
* ESIF_TRACE_ERROR
* ESIF_TRACE_WARN
* ESIF_TRACE_INFO
* ESIF_TRACE_DEBUG
* For more granular control using module-specific categories, use:
* ESIF_TRACE_DYN
* By default, the ERROR macros are automatically enabled; but may be disabled.
* Notes:
* (1) The current implementation compiles out all but the ERROR items in
* the released build.
* (2) The "module" must be define before the use of any of the macros in
* each C file by defining ESIF_DEBUG_MODULE using the ESIF_DEBUG_MOD_XXX
* definitions. (This value is an index into the module debug mask
* array.)
*/
/*
* Pre-Defined Debug Categories (Bit positions for selection mask.)
* These are translated to the TRACE LEVEL using the following:
*/
#define ESIF_TRACE_CATEGORY_ERROR 31
#define ESIF_TRACE_CATEGORY_WARN 30
#define ESIF_TRACE_CATEGORY_INFO 29
#define ESIF_TRACE_CATEGORY_DEBUG 28
#define ESIF_TRACE_CATEGORY_ENTRY_AND_EXIT 27
/*
* Convert Module Trace Category bit to Global Trace Level:
* ERROR (31) = TRACELEVEL_ERROR (1)
* WARN (30) = TRACELEVEL_WARN (2)
* INFO (29) = TRACELEVEL_INFO (3)
* DEBUG (28) = TRACELEVEL_DEBUG (4)
* All others = TRACELEVEL_DEBUG (4)
*/
#define ESIF_TRACE_CATEGORY_TO_TRACELEVEL(id) \
((((id) & 0x1F) > ESIF_TRACE_CATEGORY_DEBUG) ? (32-(id)) : ESIF_TRACELEVEL_DEBUG)
#define ESIF_TRACE_CATEGORY_DEFAULT ((u32)1 << ESIF_TRACE_CATEGORY_ERROR)
#ifdef ESIF_ATTR_OS_LINUX
#define ESIF_ALWAYSFALSE (0) /*used for do...while(0) macros */
#define ESIF_TRACENULL
#define ESIF_TRACEFUNC printk
#define ESIF_KERN_ERR KERN_ERR
#define ESIF_KERN_INFO KERN_INFO
#define ESIF_KERN_DEBUG KERN_DEBUG
#define ESIF_FILENAME __FILE__
#endif /* ESIF_ATTR_OS_LINUX */
#ifdef ESIF_ATTR_OS_WINDOWS
/* Avoids "conditional expression is constant" warnings for do...while(0) macros in Windows */
static char g_alwaysfalse;
#define ESIF_ALWAYSFALSE (!&g_alwaysfalse)
#define ESIF_TRACENULL (0)
#define ESIF_TRACEFUNC DbgPrint
#define ESIF_KERN_ERR
#define ESIF_KERN_INFO
#define ESIF_KERN_DEBUG
#define ESIF_FILENAME __FILE__
#endif /* ESIF_ATTR_OS_WINDOWS */
#define ESIF_TRACE_FMT_ERROR(fmt, ...) \
ESIF_TRACEFUNC(ESIF_KERN_ERR "!ERR! %s:%d: %s: " fmt, \
ESIF_FILENAME, __LINE__, __FUNCTION__, ##__VA_ARGS__)
#define ESIF_TRACE_FMT_WARN(fmt, ...) \
ESIF_TRACEFUNC(ESIF_KERN_DEBUG "!WRN! %s:%d: %s: " fmt, \
ESIF_FILENAME, __LINE__, __FUNCTION__, ##__VA_ARGS__)
#define ESIF_TRACE_FMT_INFO(fmt, ...) \
ESIF_TRACEFUNC(ESIF_KERN_INFO "=INF= %s:%d: %s: " fmt, \
ESIF_FILENAME, __LINE__, __FUNCTION__, ##__VA_ARGS__)
#define ESIF_TRACE_FMT_DEBUG(fmt, ...) \
ESIF_TRACEFUNC(ESIF_KERN_DEBUG "~DBG~ %s:%d: %s: " fmt, \
ESIF_FILENAME, __LINE__, __FUNCTION__, ##__VA_ARGS__)
#define ESIF_TRACE_FMT_ENTRY() \
ESIF_TRACEFUNC(ESIF_KERN_DEBUG "--> %s:%d: %s:...", \
ESIF_FILENAME, __LINE__, __FUNCTION__)
#define ESIF_TRACE_FMT_EXIT() \
ESIF_TRACEFUNC(ESIF_KERN_DEBUG "<-- %s:%d: %s:...", \
ESIF_FILENAME, __LINE__, __FUNCTION__)
#define ESIF_TRACE_FMT_EXIT_W_STATUS(status) \
ESIF_TRACEFUNC(ESIF_KERN_DEBUG "<-- %s:%d: %s: Exit status = 0x%08X", \
ESIF_FILENAME, __LINE__, __FUNCTION__, status)
#define ESIF_TRACE_CATEGORY_ON(module, category) \
((ESIF_TRACE_CATEGORY_TO_TRACELEVEL(category) <= g_esif_trace_level) && \
((1 << (module)) & g_esif_module_mask) != 0 && \
((1 << (category)) & g_esif_module_category_mask[(module)]) != 0)
#define ESIF_TRACE_ERROR(format, ...) \
do { \
if (ESIF_TRACE_CATEGORY_ON(ESIF_DEBUG_MODULE, ESIF_TRACE_CATEGORY_ERROR)) \
ESIF_TRACE_FMT_ERROR(format, ##__VA_ARGS__); \
} while (ESIF_ALWAYSFALSE)
/*
* Change these ESIF_TRACE macros to call ESIF_TRACENULL to compile out all
* non-Error trace messages from the kernel drivers and reduce the binary size
*/
#define ESIF_TRACE_WARN(format, ...) \
do { \
if (ESIF_TRACE_CATEGORY_ON(ESIF_DEBUG_MODULE, ESIF_TRACE_CATEGORY_WARN)) \
ESIF_TRACE_FMT_WARN(format, ##__VA_ARGS__); \
} while (ESIF_ALWAYSFALSE)
#define ESIF_TRACE_INFO(format, ...) \
do { \
if (ESIF_TRACE_CATEGORY_ON(ESIF_DEBUG_MODULE, ESIF_TRACE_CATEGORY_INFO)) \
ESIF_TRACE_FMT_INFO(format, ##__VA_ARGS__); \
} while (ESIF_ALWAYSFALSE)
#define ESIF_TRACE_DEBUG(format, ...) \
do { \
if (ESIF_TRACE_CATEGORY_ON(ESIF_DEBUG_MODULE, ESIF_TRACE_CATEGORY_DEBUG)) \
ESIF_TRACE_FMT_DEBUG(format, ##__VA_ARGS__); \
} while (ESIF_ALWAYSFALSE)
#define ESIF_TRACE_ENTRY() \
do { \
if (ESIF_TRACE_CATEGORY_ON(ESIF_DEBUG_MODULE, ESIF_TRACE_CATEGORY_ENTRY_AND_EXIT)) \
ESIF_TRACE_FMT_ENTRY(); \
} while (ESIF_ALWAYSFALSE)
#define ESIF_TRACE_EXIT() \
do { \
if (ESIF_TRACE_CATEGORY_ON(ESIF_DEBUG_MODULE, ESIF_TRACE_CATEGORY_ENTRY_AND_EXIT)) \
ESIF_TRACE_FMT_EXIT(); \
} while (ESIF_ALWAYSFALSE)
#define ESIF_TRACE_EXIT_W_STATUS(status) \
do { \
if (ESIF_TRACE_CATEGORY_ON(ESIF_DEBUG_MODULE, ESIF_TRACE_CATEGORY_ENTRY_AND_EXIT)) \
ESIF_TRACE_FMT_EXIT_W_STATUS(status); \
} while (ESIF_ALWAYSFALSE)
#define ESIF_TRACE_DYN(module, module_level, format, ...) \
do { \
if (ESIF_TRACE_CATEGORY_ON(module, module_level)) \
ESIF_TRACE_FMT_DEBUG(format, ##__VA_ARGS__); \
} while (ESIF_ALWAYSFALSE)
/* Initialize the enabled module debug categories */
void esif_debug_init_module_categories(void);
/* Sets the mask of modules with debugging on */
void esif_debug_set_modules(u32 module_mask);
/* Gets the mask of modules with debugging on */
void esif_debug_get_modules(u32 *module_mask_ptr);
/* Sets the debugging category mask of a particular module */
void esif_debug_set_module_category(u32 module, u32 module_level_mask);
/* Gets the debugging category mask of a particular module */
void esif_debug_get_module_category(u32 module, u32 *module_level_mask_ptr);
/* Kernel-mode Debug Module and Category Masks */
extern u32 g_esif_trace_level;
extern u32 g_esif_module_mask;
extern u32 g_esif_module_category_mask[ESIF_DEBUG_MOD_MAX];
/* Kernel Memory Statistics */
extern struct esif_memory_stats g_memstat;
#else /* NOT ESIF_ATTR_KERNEL */
/* USER Mode Debug Interface */
#ifdef ESIF_ATTR_OS_WINDOWS
/* Avoid "conditional expression is constant" warnings in macros */
static char g_alwaysfalse;
#define ESIF_ALWAYSFALSE (!&g_alwaysfalse)
/* Avoid Klocworks "suspicious semicolon" warnings */
#define ESIF_TRACENULL (0)
#define ESIF_TRACEFUNC CMD_OUT
#define ESIF_FILENAME __FILE__
#endif /* ESIF_ATTR_OS_WINDOWS */
#ifdef ESIF_ATTR_OS_LINUX
#define ESIF_ALWAYSFALSE (0)
#define ESIF_TRACENULL
#define ESIF_TRACEFUNC printf
#define ESIF_FILENAME __FILE__
#endif
/* Enumerated Type Base Macros */
#define ENUMDECL(ENUM) ENUM,
#define ENUMLIST(ENUM) {ENUM, #ENUM},
#define ENUMSWITCH(ENUM) case ENUM: return #ENUM;break;
/* Enumerated Type Macros with Explicit Values */
#define ENUMDECL_VAL(ENUM, VAL) ENUM = VAL,
#define ENUMLIST_VAL(ENUM, VAL) ENUMLIST(ENUM)
#define ENUMSWITCH_VAL(ENUM, VAL) ENUMSWITCH(ENUM)
/* Trace Module and Route Masks */
typedef u32 esif_tracemask_t;
typedef u8 esif_traceroute_t;
#define esif_tracemask_fmt "%u" // %u or %llu
#define esif_tracemask_fmtx "%x" // %x or %llx
#define ESIF_TRACEMASK_MAX 32
#define ESIF_TRACEMAPPING_MAX 256
/*
* ESIF_TRACE_ID must be #defined in each source file before any #includes
* Otherwise the module will use settings for DEFAULT module
*/
#ifndef ESIF_TRACE_ID
# define ESIF_TRACE_ID ESIF_TRACEMODULE_DEFAULT
#endif
#define ESIF_TRACEMASK(module) ((esif_tracemask_t)1 << (module))
#pragma pack(push,1)
/* Trace Level Data */
struct esif_tracelevel_s {
const char * label; // label, i.e. "ERROR"
int level; // level, i.e, 1
esif_tracemask_t modules; // active module bitmask
esif_traceroute_t routes; // active routes bitmask
};
#pragma pack(pop)
/* Enumerated TraceModule User Mode Values */
#define ENUM_TRACEMODULE(ENUM) \
ENUM(ESIF_TRACEMODULE_DEFAULT) /* Generic Module - Use Default Trace Settings*/ \
ENUM(ESIF_TRACEMODULE_DPTF) /* DPTF Loadable App */ \
\
ENUM(ESIF_TRACEMODULE_CCB) /* CCB Modules mixed with Kernel Tracing */ \
ENUM(ESIF_TRACEMODULE_SHELL) /* ESIF Shell */ \
ENUM(ESIF_TRACEMODULE_UF) /* UF Main */ \
\
ENUM(ESIF_TRACEMODULE_ACTION) /* Actions */ \
ENUM(ESIF_TRACEMODULE_APP) /* Apps */ \
ENUM(ESIF_TRACEMODULE_CONJURE) /* Conjure */ \
ENUM(ESIF_TRACEMODULE_DSP) /* DSPs */ \
ENUM(ESIF_TRACEMODULE_EVENT) /* Events */ \
ENUM(ESIF_TRACEMODULE_IPC) /* IPC */ \
ENUM(ESIF_TRACEMODULE_PARTICIPANT) /* Upper Participants */ \
ENUM(ESIF_TRACEMODULE_PRIMITIVE) /* Primitives */ \
ENUM(ESIF_TRACEMODULE_SERVICE) /* Services */ \
ENUM(ESIF_TRACEMODULE_TEST) /* Tests */ \
\
ENUM(ESIF_TRACEMODULE_DATAVAULT) /* DataVaults/DataCache/DataBank */ \
ENUM(ESIF_TRACEMODULE_EQL) /* EQL Parser/IString/EsifData */ \
ENUM(ESIF_TRACEMODULE_WEBSERVER) /* Web Socket Server */ \
\
ENUM(ESIF_TRACEMODULE_WINDOWS) /* Windows General */ \
ENUM(ESIF_TRACEMODULE_ACTWIRELESS) /* Windows ACT Wireless */ \
ENUM(ESIF_TRACEMODULE_UMDF) /* Windows UMDF */ \
enum esif_tracemodule {
ENUM_TRACEMODULE(ENUMDECL)
};
#define ESIF_TRACEMASK_ALL ((esif_tracemask_t)-1) /* all bits */
#pragma pack(push,1)
struct esif_tracemodule_s {
const char *module;
enum esif_tracemodule module_id;
};
#pragma pack(pop)
/* ESIF_UF Trace Routes */
#define ESIF_TRACEROUTE_CONSOLE 1 /* Shell Console */
#define ESIF_TRACEROUTE_EVENTLOG 2 /* Windows=EventLog Linux=syslog */
#define ESIF_TRACEROUTE_DEBUGGER 4 /* Windows=DebugView Linux=syslog */
#define ESIF_TRACEROUTE_LOGFILE 8 /* Trace Log File (create with "trace log open <file>") */
/* Do not access these functions and variables directly in any code, just the macros at the bottom */
#ifdef __cplusplus
extern "C" {
#endif
extern int g_traceLevel;
extern const char *g_tracelabel[];
extern int g_traceLevel_max;
extern struct esif_tracelevel_s g_traceinfo[];
extern const enum esif_tracemodule EsifTraceModule_FromString(const char *name);
extern const char *EsifTraceModule_ToString(enum esif_tracemodule val);
extern int EsifTraceMessage(esif_tracemask_t module, int level, const char *func, const char *file, int line, const char *msg, ...);
#ifdef __cplusplus
}
#endif
/* Test whether Tracing is currently active for the given module and level based on the currrent trace level*/
#define ESIF_TRACEACTIVE(module, level) ((g_traceLevel >= (level)) && !!(g_traceinfo[level].modules & (module)))
/* Test whether Tracing is currently enabled for the given module and level (regardless of current trace level) */
#define ESIF_TRACEENABLED(module, level) (!!(g_traceinfo[level].modules & (module)))
/* Conditionally route trace message if given module/level are currently active, based on the current trace level.
* Optional arguments are not evaluated and message string not created if message not routed
*/
#define ESIF_DOTRACE_IFACTIVE(module, level, msg, ...) \
do { \
if (ESIF_TRACEACTIVE(module, level)) { \
EsifTraceMessage(module, level, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__); \
} \
} while (ESIF_ALWAYSFALSE)
/*
* Conditionally route trace message if given module/level are currently enabled, regardless of the current trace level.
* Optional arguments are not evaluated and message string not created if message not routed
*/
#define ESIF_DOTRACE_IFENABLED(module, level, msg, ...) \
do { \
if (ESIF_TRACEENABLED(module, level)) { \
EsifTraceMessage(module, level, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__); \
} \
} while (ESIF_ALWAYSFALSE)
/* Always route trace message regardless of current module masks and trace level */
#define ESIF_DOTRACE_ALWAYS(module, level, msg, ...) \
EsifTraceMessage(module, level, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__)
/* Never route a trace message and compile it out of the binary */
#define ESIF_DOTRACE_NEVER(mod, lev, msg, ...) ((void)0)
/*
* Change ESIF_DOTRACE_INACTIVE to ESIF_DOTRACE_NEVER in the following macro
* to compile out all ESIF_TRACE_DEBUG messages from the Upper Framework binaries.
*/
#define ESIF_DOTRACE_IFCOMPILED(mod, lev, msg, ...) ESIF_DOTRACE_IFACTIVE(mod, lev, msg, ##__VA_ARGS__)
/* Default User-Mode Trace Level at startup */
#define ESIF_TRACELEVEL_DEFAULT ESIF_TRACELEVEL_ERROR
/*****************************************************************************
* App Interface for Trace messages. Only use these macros in source modules.
****************************************************************************/
/*
* ESIF_TRACE_XXXX messages are conditionally routed depending on current trace level and module masks.
* ESIF_DOTRACE_IFCOMPILED is used for trace levels that may be conditionally compiled out of the binary
*/
#define ESIF_TRACE_FATAL(msg, ...) ESIF_DOTRACE_IFACTIVE(ESIF_TRACEMASK(ESIF_TRACE_ID), ESIF_TRACELEVEL_FATAL, msg, ##__VA_ARGS__)
#define ESIF_TRACE_ERROR(msg, ...) ESIF_DOTRACE_IFACTIVE(ESIF_TRACEMASK(ESIF_TRACE_ID), ESIF_TRACELEVEL_ERROR, msg, ##__VA_ARGS__)
#define ESIF_TRACE_WARN(msg, ...) ESIF_DOTRACE_IFACTIVE(ESIF_TRACEMASK(ESIF_TRACE_ID), ESIF_TRACELEVEL_WARN, msg, ##__VA_ARGS__)
#define ESIF_TRACE_INFO(msg, ...) ESIF_DOTRACE_IFACTIVE(ESIF_TRACEMASK(ESIF_TRACE_ID), ESIF_TRACELEVEL_INFO, msg, ##__VA_ARGS__)
#define ESIF_TRACE_DEBUG(msg, ...) ESIF_DOTRACE_IFCOMPILED(ESIF_TRACEMASK(ESIF_TRACE_ID), ESIF_TRACELEVEL_DEBUG, msg, ##__VA_ARGS__)
/* ESIF_TRACE_IFACTIVE messages are always compiled into binary and routed if module/level active, based on current trace level */
#define ESIF_TRACE_IFACTIVE(module, level, msg, ...) ESIF_DOTRACE_IFACTIVE(ESIF_TRACEMASK(module), level, msg, ##__VA_ARGS__)
/* ESIF_TRACE_IFENABLED messages are always compiled into binary and routed if module/level enabled, regardles of current trace level */
#define ESIF_TRACE_IFENABLED(module, level, msg, ...) ESIF_DOTRACE_IFENABLED(ESIF_TRACEMASK(module), level, msg, ##__VA_ARGS__)
/* Use these for tracing Entry/Exit of functions */
#define ESIF_TRACE_ENTRY() ESIF_TRACE_DEBUG("Entering Function")
#define ESIF_TRACE_EXIT() ESIF_TRACE_DEBUG("Exiting Function")
/* Use these for tracing Entry/Exit of functions that you need logged at INFO level (rare) */
#define ESIF_TRACE_ENTRY_INFO() ESIF_TRACE_INFO("Entering Function")
#define ESIF_TRACE_EXIT_INFO() ESIF_TRACE_INFO("Exiting Function")
#endif /* ESIF_ATTR_USER */
#endif /* _ESIF_DEBUG_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,190 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_DOMAIN_H_
#define _ESIF_DOMAIN_H_
#include "esif.h"
#ifdef ESIF_ATTR_KERNEL
/*
** Domain
*/
#define ESIF_DOMAIN_VERSION 0x1
#define ESIF_DOMAIN_MAX 10
#define ESIF_DOMAIN_TEMP_INVALID 0xffffffff
/* Translate Qualifier To Index */
static ESIF_INLINE enum esif_rc esif_lp_domain_index (
u16 domain,
u8 *index
)
{
enum esif_rc rc = ESIF_OK;
switch (domain) {
case '0D': /* D0 */
*index = 0;
break;
case '1D': /* D1 */
*index = 1;
break;
case '2D': /* D2 */
*index = 2;
break;
case '3D': /* D3 */
*index = 3;
break;
case '4D': /* D4 */
*index = 4;
break;
case '5D': /* D5 */
*index = 5;
break;
case '6D': /* D6 */
*index = 6;
break;
case '7D': /* D7 */
*index = 7;
break;
case '8D': /* D8 */
*index = 8;
break;
case '9D': /* D9 */
*index = 9;
break;
default:
rc = ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS;
break;
}
return rc;
}
struct esif_lp_domain {
u8 instance; /* Instance */
esif_flags_t capabilities; /* Capabilities */
enum esif_domain_type domainType; /* Domain Type */
u16 id; /* Domain ID */
char *name_ptr; /* Name */
char *desc_ptr; /* Describe Qualifier */
struct esif_lp *lp_ptr; /* Lower Participant Back Ref
* */
/* ESIF will only poll when it has to otherwise it will utilize hardware
** provided programmable thresholds and notifications but if it has no
** other method it will poll.
*/
u8 poll; /* Is Polling? */
esif_flags_t poll_mask; /* Want To Poll? */
/* Timer For Polling */
esif_ccb_timer_t timer; /* Periodic Work Timer */
u32 timer_period_msec; /* Periodic Interval */
/* RAPL / Power */
u32 rapl_energy_units_current; /* Last energy accumulator read */
u32 rapl_energy_units_last; /* Read before for calc delta */
u32 rapl_energy_units_per_sec; /* Actual Energy Units Used Per Sec */
u32 rapl_power; /* Calculated Power */
/* Temperature Thresholds */
esif_temp_t temp_cache0; /* Cache Lower */
esif_temp_t temp_cache1; /* Cache Upper */
esif_temp_t temp_aux0; /* Lower */
/* enum esif_lp_domain_th_state temp_aux0_state; / * state machine
* state * / */
u8 temp_notify_sent;
esif_temp_t temp_aux1; /* Upper */
/* enum esif_lp_domain_th_state temp_aux1_state; / * State machine
* state * / */
esif_temp_t temp_hysteresis; /* Lower Hysteresis */
/* Power Thresholds */
esif_power_t power_aux0; /* Lower */
esif_power_t power_aux1; /* Upper */
esif_power_t power_hysteresis; /* Lower Hysteresis */
/* Unit Data */
esif_temp_t temp_tjmax; /* Tjmax */
esif_power_t unit_power; /* Power Unit */
esif_power_t unit_energy; /* Energt Unit */
u32 unit_time; /* Time Unit */
#ifdef ESIF_ATTR_OS_LINUX
struct device device; /* Lower Participant Qualifier Class Device */
struct thermal_zone_device *tzd_ptr; /* Thermal Zone Device If Any */
struct thermal_cooling_device *cdev_ptr; /* Cooling Device If Any */
#endif
};
#endif /* ESIF_ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
#endif /* ESIF_ATTR_USER */
#endif /* _ESIF_DOMAIN_H_ */
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,357 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_DSP_H_
#define _ESIF_DSP_H_
#define ESIF_DSP_NAME_LEN (12 + 1)
#include "esif_participant.h"
/* EDP Struct Referred By Both LF and UF */
struct edp_dir {
unsigned int signature;
unsigned int version;
unsigned int cpc_offset;
unsigned int fpc_offset;
};
#ifdef ESIF_ATTR_KERNEL
/* Compact Primitive Catalog */
#include "esif.h"
#include "esif_cpc.h"
#define THIS const struct esif_lp_dsp *THIS
/* Lower Framework DSP
* Kernel version of DSP is a subset of the full DSP and is known as a Compact
* Primitive Catalog. The CPC contains only the abosulte essentials for the
* kernel driver.
*/
struct esif_lp_dsp {
/* private: */
/* Pointers Will Point Into Raw CPC Block Of Memory */
esif_flags_t *capability_ptr; /* Enhanced Capability */
esif_string code_ptr; /* Code Short Name */
u8 *domain_count_ptr; /* Domain Count */
struct domain *domains_ptr; /* Domains */
u8 *ver_major_ptr; /* DSP Content Major */
u8 *ver_minor_ptr; /* DSP Content Minor */
/* Raw Cannonical Data For DSP Pointeers */
struct esif_lp_cpc *cpc_ptr;
/* DSP Hash Table Will Contain Pointers Into CPC */
struct esif_hash_table *ht_ptr;
struct esif_link_list *algo_ptr; /* Algorithm */
struct esif_link_list *evt_ptr; /* Event */
esif_ccb_lock_t lock; /* DSP Lock */
void *table; /* Add'l Static Or Dynamic Table(s) */
u32 table_size; /* Table(s) Size Of Each */
/* public: */
u32 (*get_id)(THIS);
void (*set_id)(THIS, u32 id);
esif_string (*get_code)(THIS);
u8 (*get_domain_count)(THIS);
esif_flags_t (*get_domain_capability)(THIS, u8 domain_index);
enum esif_domain_type (*get_domain_type)(THIS, u8 domain_index);
u16 (*get_domain_id)(THIS, u8 domain_index);
esif_string (*get_domain_desc)(THIS, u8 domain_index);
esif_string (*get_domain_name)(THIS, u8 domain_index);
u8 (*get_ver_major)(THIS);
u8 (*get_ver_minor)(THIS);
u32 (*get_temp_tc1) (THIS,
const enum esif_action_type action);
u32 (*get_temp_tc2)(THIS, const enum esif_action_type action);
enum esif_rc (*insert_primitive)(THIS,
struct esif_cpc_primitive *
primitive_ptr);
enum esif_rc (*insert_algorithm)(THIS,
struct esif_cpc_algorithm *
algorithm_ptr);
enum esif_rc (*insert_event)(THIS, struct esif_cpc_event *event_ptr);
struct esif_lp_primitive * (*get_primitive)(THIS,
const struct
esif_primitive_tuple *
tuple_ptr);
struct esif_lp_action * (*get_action)(THIS,
struct esif_lp_primitive *
primitive_ptr, u8 index);
struct esif_cpc_algorithm * (*get_algorithm)(THIS,
const enum
esif_action_type
action_type);
u32 (*dsp_has_algorithm)( THIS, const enum esif_algorithm_type);
struct esif_cpc_event * (*get_event)(THIS, u32 event);
};
#undef THIS
/* Load DSP */
enum esif_rc esif_dsp_load (struct esif_lp *lp_ptr,
const struct esif_data *cpc_ptr);
void esif_dsp_unload (struct esif_lp *lp_ptr);
/* Init / Exit */
enum esif_rc esif_dsp_init (void);
void esif_dsp_exit (void);
#endif /* ESIF_ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
#include "esif_uf_fpc.h"
#define THIS struct esif_up_dsp *THIS
#define MAX_DSP_MANAGER_ENTRY 128
#define ESIF_DSP_NAMESPACE "dsp" /* DSP DataVault Namespace */
#define ESIF_DSP_OVERRIDE_NAMESPACE "override" /* DSP Overrides DV name */
#define ESIF_EDP_DV_PRIORITY 0 /* 0=EDP on disk overrides EDP
* in DataVault, 1=EDP in
* DataVault overrides EDP on
* disk */
/* DSP Manager Entry */
struct esif_uf_dme {
struct esif_up_dsp *dsp_ptr; /* DSP Instance */
struct esif_ccb_file *file_ptr;/* Optional ESIF File Instance */
struct esif_fpc *fpc_ptr; /* FPC buffer (0 if static) */
};
/* DSP Manager */
struct esif_uf_dm {
UInt8 dme_count; /* Current Reference Count */
struct esif_uf_dme dme[MAX_DSP_MANAGER_ENTRY]; /* Maximum Participants
* */
esif_ccb_lock_t lock; /* Package Manager Lock
* */
};
/* Upper Framework DSP */
struct esif_up_dsp {
/*
* PRIVATE
*/
/* Pointers Will Point Into PC Block Of Memory */
esif_string code_ptr; /* Code Short Name */
esif_string desc_ptr; /* Description */
esif_string type; /* Unique Identifier */
UInt8 *bus_enum; /* Bus Enumeration Type */
UInt8 *ver_major_ptr; /* Content Major */
UInt8 *ver_minor_ptr; /* Content Minor */
/* ACPI */
esif_string acpi_device; /* ACPI Device e.g. INT3400 */
esif_string acpi_scope; /* _SB.PCI0.B0D4 */
esif_string acpi_type; /* ACPI Type */
/* PCI */
esif_string vendor_id; /* Vendor ID 8086 For Intel */
esif_string device_id; /* Device ID */
esif_string pci_bus; /* PCI Bus */
esif_string pci_bus_device;/* PCI Device */
esif_string pci_function; /* PCI Function */
/* Attributes */
/* UInt32 *capability_ptr; / * Enhanced Capability * / */
UInt32 *domain_count; /* Domain Count */
/* Raw Cannonical Data For DSP Pointeers */
struct esif_uf_pc *pc_ptr;
/* DSP Hash Table Will Contain Pointers Into CPC*/
struct esif_hash_table *ht_ptr;
struct esif_link_list *domain_ptr; /* Domain */
struct esif_link_list *cap_ptr; /* Capability */
struct esif_link_list *algo_ptr; /* Algorithm */
struct esif_link_list *evt_ptr; /* Events */
/* Lock */
esif_ccb_lock_t lock; /* DSP Lock*/
/*
* PUBLIC INTRERFACE
*/
UInt32 (*get_id) (THIS);
void (*set_id) (THIS, u32 id);
UInt32 (*get_domain_count)(THIS);
/* Description */
esif_string (*get_code) (THIS);
esif_string (*get_desc) (THIS);
esif_guid_t * (*get_type) (THIS);
UInt8 (*get_bus_enum) (THIS);
UInt8 (*get_ver_major) (THIS);
UInt8 (*get_ver_minor) (THIS);
/* ACPI */
esif_string (*get_acpi_device) (THIS);
esif_string (*get_acpi_scope) (THIS);
UInt8 (*get_acpi_type) (THIS);
/* PCI */
UInt32 (*get_device_id) (THIS);
UInt32 (*get_vendor_id) (THIS);
UInt8 (*get_pci_bus) (THIS);
UInt8 (*get_pci_bus_device) (THIS);
UInt8 (*get_pci_function) (THIS);
/* Attributes */
UInt32 (*get_temp_tc1) (THIS, enum esif_action_type action);
UInt32 (*get_temp_tc2) (THIS, enum esif_action_type action);
enum esif_rc (*insert_primitive)(THIS,
EsifFpcPrimitivePtr primitive_ptr);
enum esif_rc (*insert_algorithm)(THIS,
struct esif_fpc_algorithm *
algorithm_ptr);
enum esif_rc (*insert_domain) (THIS,
struct esif_fpc_domain *domain_ptr);
enum esif_rc (*insert_event) (THIS,
struct esif_fpc_event *event_ptr);
EsifFpcPrimitivePtr (*get_primitive)(THIS,
const struct esif_primitive_tuple
*tuple_ptr);
EsifFpcActionPtr (*get_action) (THIS,
EsifFpcPrimitivePtr primitive_ptr,
u8 index);
struct esif_fpc_algorithm * (*get_algorithm)(THIS,
const enum
esif_action_type
action_type);
struct esif_fpc_event * (*get_event_by_type)(THIS,
const enum
esif_event_type event_type);
struct esif_fpc_event * (*get_event_by_guid)(THIS,
const esif_guid_t guid);
struct esif_fpc_domain * (*get_domain) (THIS, const u32 index);
};
#undef THIS
typedef struct esif_up_dsp EsifDsp, *EsifDspPtr, **EsifDspPtrLocation;
enum esif_uf_dm_query_type {
ESIF_UF_DM_QUERY_TYPE_ACPI = 0,
ESIF_UF_DM_QUERY_TYPE_PCI,
ESIF_UF_DM_QUERY_TYPE_PLATFORM
};
/* Fields may be blank to indicate don't cares */
struct esif_uf_dm_query_acpi {
esif_string acpi_device; /* Weight 8 */
esif_string acpi_type; /* Weight 4 */
esif_string acpi_uid; /* Weight 2 */
esif_string acpi_scope; /* Weight 1 */
};
/* Fields may be blank to indicate don't cares */
struct esif_uf_dm_query_pci {
EsifString pci_did; /* Weight 8 */
EsifString pci_vid; /* Weight 4 */
};
/* Fields may be blank to indicate don't cares */
struct esif_uf_dm_query_plat {
esif_string plat_type; /* Weight 2 */
esif_string plat_name; /* Weight 1 */
};
/* Query */
struct esif_ipc_event_data_create_participant;
#ifdef __cplusplus
extern "C" {
#endif
esif_string esif_uf_dm_query(enum esif_uf_dm_query_type query_type, void *qry_ptr);
struct esif_up_dsp *esif_uf_dm_select_dsp_by_code (esif_string code);
esif_string esif_uf_dm_select_dsp (eEsifParticipantOrigin origin, void *piPtr);
EsifString esif_uf_dm_select_dsp_for_participant(struct esif_ipc_event_data_create_participant *data_ptr);
/* Init / Exit */
enum esif_rc EsifDspInit (void);
void EsifDspExit (void);
/* DSP Manager Init */
enum esif_rc EsifDspMgrInit (void);
/* DSP Manager Exit */
void EsifDspMgrExit (void);
#ifdef __cplusplus
}
#endif
#endif /* ESIF_ATTR_USER */
#endif /* _ESIF_DSP_H_ */
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,272 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_EVENT_H_
#define _ESIF_EVENT_H_
#include "esif.h"
#define ESIF_EVENT_VERSION 0x1
/* Event Priority */
enum esif_event_priority {
ESIF_EVENT_PRIORITY_NORMAL = 0,
ESIF_EVENT_PRIORITY_LOW,
ESIF_EVENT_PRIORITY_HIGH
};
/* Event Priority String */
static ESIF_INLINE char *
esif_event_priority_str(enum esif_event_priority priority)
{
#define CREATE_EVENT_PRIORITY(ep, str) case ep: str = (esif_string) #ep; break;
esif_string str = (esif_string)ESIF_NOT_AVAILABLE;
switch (priority) {
CREATE_EVENT_PRIORITY(ESIF_EVENT_PRIORITY_NORMAL, str)
CREATE_EVENT_PRIORITY(ESIF_EVENT_PRIORITY_LOW, str)
CREATE_EVENT_PRIORITY(ESIF_EVENT_PRIORITY_HIGH, str)
}
return str;
}
/* Event Type */
enum esif_event_type {
/* App Events */
ESIF_EVENT_APP_CONNECTED_STANDBY_ENTRY = 0, /* Enter conn standby */
ESIF_EVENT_APP_CONNECTED_STANDBY_EXIT = 1, /* Exit conn standby */
ESIF_EVENT_APP_ACTIVE_RELATIONSHIP_CHANGED = 2,
ESIF_EVENT_APP_THERMAL_RELATIONSHIP_CHANGED = 3,
ESIF_EVENT_APP_FOREGROUND_CHANGED = 4, /* Foreground app changed */
ESIF_EVENT_PARTICIPANT_SUSPEND = 5, /* Suspend Upper Framework */
ESIF_EVENT_PARTICIPANT_RESUME = 6, /* Resume Upper Framework */
ESIF_EVENT_OS_LPM_MODE_CHANGED = 23, /* LPM Mode Changed */
ESIF_EVENT_APP_PASSIVE_TABLE_CHANGED = 24, /* Passive Tbl Changed */
/* Domain Events */
/* Config TDP Capability changed (Configurable TDP) */
ESIF_EVENT_DOMAIN_CTDP_CAPABILITY_CHANGED = 7,
ESIF_EVENT_DOMAIN_CORE_CAPABILITY_CHANGED = 8, /* For future use */
/* Display control upper/lower limits changed. */
ESIF_EVENT_DOMAIN_DISPLAY_CAPABILITY_CHANGED = 9,
/* Current Display brightness status changed due to usr or other override */
ESIF_EVENT_DOMAIN_DISPLAY_STATUS_CHANGED = 10,
/* Performance Control Upper/Lower Limits Changed */
ESIF_EVENT_DOMAIN_PERF_CAPABILITY_CHANGED = 11,
/* For future use */
ESIF_EVENT_DOMAIN_PERF_CONTROL_CHANGED = 12,
/* Power Control Capability Changed (Participant)*/
ESIF_EVENT_DOMAIN_POWER_CAPABILITY_CHANGED = 13,
/* Programmable Threshold Power Event */
ESIF_EVENT_DOMAIN_POWER_THRESHOLD_CROSSED = 14,
ESIF_EVENT_DOMAIN_PRIORITY_CHANGED = 15, /* Domain priority changed. */
/* Temperature Threshold Changed (Participant)*/
ESIF_EVENT_DOMAIN_TEMP_THRESHOLD_CROSSED = 16,
/* Participant Events */
/* Participant Specific Information Changed. */
ESIF_EVENT_PARTICIPANT_SPEC_INFO_CHANGED = 17,
/*
** ESIF EVENTS
*/
/* Create Upper Framework (Participant) */
ESIF_EVENT_PARTICIPANT_CREATE = 18,
/* Destroy Upper Framework (Participant) */
ESIF_EVENT_PARTICIPANT_UNREGISTER = 19, /* Unregister UF Participant */
/* Shutdown Upper Framework (Participant) */
ESIF_EVENT_PARTICIPANT_SHUTDOWN = 20,
/*
** Driver Events (To Be Mapped To ESIF Event)
*/
ESIF_EVENT_ACPI = 21, /* ACPI events, ex. ART changed */
/*
** UUID Changed Events
*/
ESIF_EVENT_COOLING_MODE_POWER_LIMIT_CHANGED = 22,
ESIF_EVENT_PASSIVE_TABLE_CHANGED = 24,
ESIF_EVENT_COOLING_MODE_ACOUSTIC_LIMIT_CHANGED = 25,
ESIF_EVENT_SENSOR_ORIENTATION_CHANGED = 26,
ESIF_EVENT_SENSOR_SPATIAL_ORIENTATION_CHANGED = 27,
ESIF_EVENT_SENSOR_PROXIMITY_CHANGED = 28,
ESIF_EVENT_SYSTEM_COOLING_POLICY_CHANGED = 29,
ESIF_EVENT_LPM_MODE_CHANGED = 30,
ESIF_EVENT_OS_CTDP_CAPABILITY_CHANGED = 31,
ESIF_EVENT_RF_PROFILE_CHANGED = 32,
ESIF_EVENT_RF_CONNECTION_STATUS_CHANGED = 33,
ESIF_EVENT_LOG_VERBOSITY_CHANGED = 34
};
#ifdef ESIF_ATTR_USER
typedef enum esif_event_type eEsifEventType;
#endif
/* Event */
struct esif_event {
u16 size; /* Event Size Including Data */
u8 version; /* Event Version */
u64 id; /* Event Transaction ID */
esif_ccb_time_t timestamp; /* Event Timestamp */
enum esif_event_type type; /* Event Type */
enum esif_event_priority priority; /* Event Priority */
u8 src; /* Event Source */
u8 dst; /* Event Destination */
u16 dst_domain_id; /* Event Destination Domain ID */
u16 data_size; /* Event Data Size */
};
#ifdef __cplusplus
extern "C" {
#endif
/* Event Type String */
static ESIF_INLINE char *esif_event_type_str(enum esif_event_type type)
{
#define CREATE_EVENT_TYPE(et, str) case et: str = (esif_string) #et; break;
esif_string str = (esif_string)ESIF_NOT_AVAILABLE;
switch (type) {
CREATE_EVENT_TYPE(ESIF_EVENT_APP_CONNECTED_STANDBY_ENTRY, str)
CREATE_EVENT_TYPE(ESIF_EVENT_APP_CONNECTED_STANDBY_EXIT, str)
CREATE_EVENT_TYPE(ESIF_EVENT_APP_THERMAL_RELATIONSHIP_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_APP_ACTIVE_RELATIONSHIP_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_APP_FOREGROUND_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_OS_LPM_MODE_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_APP_PASSIVE_TABLE_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_DOMAIN_CTDP_CAPABILITY_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_DOMAIN_CORE_CAPABILITY_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_DOMAIN_DISPLAY_CAPABILITY_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_DOMAIN_DISPLAY_STATUS_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_DOMAIN_PERF_CAPABILITY_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_DOMAIN_PERF_CONTROL_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_DOMAIN_POWER_CAPABILITY_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_DOMAIN_POWER_THRESHOLD_CROSSED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_DOMAIN_PRIORITY_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_DOMAIN_TEMP_THRESHOLD_CROSSED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_PARTICIPANT_SPEC_INFO_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_PARTICIPANT_CREATE, str)
CREATE_EVENT_TYPE(ESIF_EVENT_PARTICIPANT_UNREGISTER, str)
CREATE_EVENT_TYPE(ESIF_EVENT_PARTICIPANT_RESUME, str)
CREATE_EVENT_TYPE(ESIF_EVENT_PARTICIPANT_SHUTDOWN, str)
CREATE_EVENT_TYPE(ESIF_EVENT_PARTICIPANT_SUSPEND, str)
CREATE_EVENT_TYPE(ESIF_EVENT_ACPI, str)
CREATE_EVENT_TYPE(ESIF_EVENT_COOLING_MODE_POWER_LIMIT_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_COOLING_MODE_ACOUSTIC_LIMIT_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_SENSOR_ORIENTATION_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_SENSOR_SPATIAL_ORIENTATION_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_SENSOR_PROXIMITY_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_SYSTEM_COOLING_POLICY_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_LPM_MODE_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_OS_CTDP_CAPABILITY_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_RF_PROFILE_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_RF_CONNECTION_STATUS_CHANGED, str)
CREATE_EVENT_TYPE(ESIF_EVENT_LOG_VERBOSITY_CHANGED, str)
}
return str;
}
/*
* Allocate Event
* parameters:
* type - Event Type
* size - Event Size Not Including Header
* priority - Event Priority For Queuing
* src - Source Of Event
* dst - Destination Of Event
* data - Data To Copy To Event If Any.
*
* returns:
* esif_event or NULL;
*/
struct esif_event *esif_event_allocate(const enum esif_event_type type,
const u16 size,
const enum esif_event_priority priority,
const u8 src,
const u8 dst,
const u16 dst_domain_id,
const void *data_ptr);
void esif_event_free(const struct esif_event *event_ptr);
struct esif_ipc;
struct esif_ipc *esif_event_queue_pull(void);
enum esif_rc esif_event_queue_push(struct esif_ipc *ipc_ptr);
enum esif_rc esif_event_queue_requeue(struct esif_ipc *ipc_ptr);
u32 esif_event_queue_size(void);
enum esif_rc esif_event_init(void);
void esif_event_exit(void);
struct esif_ipc_event_header;
void EsifEventProcess(struct esif_ipc_event_header *eventPtr);
#ifdef __cplusplus
}
#endif
#endif /* _ESIF_EVENT_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,263 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_hash_table.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified
* against Windows SDK/DDK included headers which we have no control over.
*
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
#ifdef ESIF_ATTR_KERNEL
/* Debug Logging Defintions */
#define INIT_DEBUG 0
#define CREATE_DEBUG 1
#define DESTROY_DEBUG 2
#define PUT_DEBUG 3
#define GET_DEBUG 4
#define HASH_DEBUG 5
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_HASH, INIT_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_CREATE(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_HASH, CREATE_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_DESTROY(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_HASH, DESTROY_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_PUT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_HASH, PUT_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_GET(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_HASH, GET_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_HASH(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_HASH, HASH_DEBUG, format, ##__VA_ARGS__)
#endif /* ESIF_ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
#define ESIF_TRACE_DYN_HASH NO_ESIF_DEBUG
#define ESIF_TRACE_DYN_GET NO_ESIF_DEBUG
#define ESIF_TRACE_DYN_PUT NO_ESIF_DEBUG
#define ESIF_TRACE_DYN_CREATE NO_ESIF_DEBUG
#define ESIF_TRACE_DYN_DESTROY NO_ESIF_DEBUG
#define ESIF_TRACE_DYN_INIT NO_ESIF_DEBUG
#endif /* ESIF_ATTR_USER */
/*
* follows the FNV-1a method of hash creation
* http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-1a
*/
static const u32 FNV_PRIME = 16777619;
/* Hash */
static u32 esif_hash_table_hash(
u8 *data_ptr,
u32 data_length
)
{
u32 hash_value = 0;
u32 offset = 0;
for (offset = 0; offset < data_length; ++offset) {
hash_value = hash_value ^ data_ptr[offset];
hash_value = hash_value * FNV_PRIME;
}
ESIF_TRACE_DYN_HASH("%s: hash %08x\n", ESIF_FUNC, hash_value);
return hash_value;
}
/* Get Item From Hash Table */
struct esif_link_list *esif_hash_table_get_item(
u8 *key_ptr,
u32 key_length,
struct esif_hash_table *hash_table_ptr
)
{
struct esif_link_list *ll_ptr = NULL;
u32 hash_index =
esif_hash_table_hash(key_ptr,
key_length) % hash_table_ptr->size;
ll_ptr = hash_table_ptr->table[hash_index];
ESIF_TRACE_DYN_GET(
"%s: key %p, key size %d, table %p index %d llr %p\n",
ESIF_FUNC,
key_ptr,
key_length,
hash_table_ptr,
hash_index,
ll_ptr);
return ll_ptr;
}
/* Put Item In Hash Table */
enum esif_rc esif_hash_table_put_item(
u8 *key_ptr,
u32 key_length,
void *item_ptr,
struct esif_hash_table *hash_table_ptr
)
{
u32 hash_index =
esif_hash_table_hash(key_ptr,
key_length) % hash_table_ptr->size;
esif_link_list_node_add(hash_table_ptr->table[hash_index],
esif_link_list_create_node(item_ptr));
ESIF_TRACE_DYN_PUT(
"%s: key %p, key size %d, item %p, table %p index %d\n",
ESIF_FUNC,
key_ptr,
key_length,
item_ptr,
hash_table_ptr,
hash_index);
return ESIF_OK;
}
/* Create Hash Table */
struct esif_hash_table *esif_hash_table_create(u32 size)
{
u32 table_index = 0;
struct esif_hash_table *new_hash_table_ptr = NULL;
new_hash_table_ptr = (struct esif_hash_table *)
esif_ccb_mempool_zalloc(ESIF_MEMPOOL_TYPE_HASH);
if (NULL == new_hash_table_ptr)
return NULL;
new_hash_table_ptr->size = size;
new_hash_table_ptr->table = (struct esif_link_list **)
esif_ccb_malloc(sizeof(struct esif_link_list *) * size);
if (new_hash_table_ptr->table == NULL) {
esif_ccb_mempool_free(ESIF_MEMPOOL_TYPE_HASH,
new_hash_table_ptr);
return NULL;
}
for (table_index = 0; table_index < size; ++table_index) {
ESIF_TRACE_DYN_CREATE("%s: create linked list %d\n",
ESIF_FUNC,
table_index);
new_hash_table_ptr->table[table_index] =
esif_link_list_create();
}
ESIF_TRACE_DYN_CREATE("%s: have hash table %p\n",
ESIF_FUNC,
new_hash_table_ptr);
return new_hash_table_ptr;
}
/* Destroy Hash Table */
void esif_hash_table_destroy(struct esif_hash_table *hash_table_ptr)
{
u32 table_index;
ESIF_TRACE_DYN_DESTROY("%s: destorying hash table %p\n",
ESIF_FUNC,
hash_table_ptr);
for (table_index = 0; table_index < hash_table_ptr->size;
++table_index) {
ESIF_TRACE_DYN_DESTROY("%s: destroy linked list %d\n",
ESIF_FUNC,
table_index);
esif_link_list_destroy(hash_table_ptr->table[table_index]);
}
esif_ccb_free(hash_table_ptr->table);
esif_ccb_mempool_free(ESIF_MEMPOOL_TYPE_HASH, hash_table_ptr);
}
/* Init */
enum esif_rc esif_hash_table_init(void)
{
struct esif_ccb_mempool *mempool_ptr = NULL;
ESIF_TRACE_DYN_INIT("%s: Initialize Primitive Hash Table\n", ESIF_FUNC);
mempool_ptr =
esif_ccb_mempool_create(ESIF_MEMPOOL_TYPE_HASH,
ESIF_MEMPOOL_FW_HASH,
sizeof(struct esif_hash_table));
if (NULL == mempool_ptr)
return ESIF_E_NO_MEMORY;
return ESIF_OK;
}
/* Exit */
void esif_hash_table_exit(void)
{
ESIF_TRACE_DYN_INIT("%s: Exit Primitive Hash Table\n", ESIF_FUNC);
}
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,98 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_HASH_TABLE_H_
#define _ESIF_HASH_TABLE_H_
#include "esif.h"
#include "esif_link_list.h"
struct esif_hash_table {
u32 size;
struct esif_link_list **table;
};
#ifdef __cplusplus
extern "C" {
#endif
struct esif_hash_table *esif_hash_table_create (u32 size);
void esif_hash_table_destroy(struct esif_hash_table *hash_table_ptr);
struct esif_link_list *esif_hash_table_get_item(u8 *key_ptr,
u32 key_length,
struct esif_hash_table *hash_table_ptr);
enum esif_rc esif_hash_table_put_item(u8 *key_ptr,
u32 key_length,
void *item_ptr,
struct esif_hash_table *hash_table_ptr);
/* Init */
enum esif_rc esif_hash_table_init (void);
void esif_hash_table_exit (void);
#ifdef __cplusplus
}
#endif
#ifdef ESIF_ATTR_USER
typedef struct esif_hash_table EsifHashTable, *EsifHashTablePtr,
**EsifHashTablePtrLocation;
#endif
#endif /* _ESIF_HASH_TABLE_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,323 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifdef ESIF_ATTR_USER
# define ESIF_TRACE_ID ESIF_TRACEMODULE_IPC
#endif
#include "esif_ipc.h"
#include "esif_primitive.h"
#include "esif_debug.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified
* against Windows SDK/DDK included headers which we have no control over.
*
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
#ifdef ESIF_ATTR_KERNEL
#define ESIF_DEBUG_MODULE ESIF_DEBUG_MOD_IPC
/* Debug Logging Defintions */
#define RESERVED0 0 /* Used By OS Version */
#define RESERVED1 1 /* Used By OS Version */
#define RESERVED2 2 /* Used By OS Version */
#define RESERVED4 3 /* Used By OS Version */
#define INIT_DEBUG 4 /* Init Debug */
#define IPC_DEBUG 5 /* IPC Debug */
#define RESERVED20 6 /* Reserved */
#define RESERVED40 7 /* Reserved */
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_IPC, INIT_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_IPC(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_IPC, IPC_DEBUG, format, ##__VA_ARGS__)
/*
* Kernel Implementation
*/
/*
******************************************************************************
* PUBLIC
******************************************************************************
*/
/* Process IPC */
struct esif_ipc *esif_ipc_process(
struct esif_ipc *ipc_ptr
)
{
struct esif_ipc *ipc_ret_ptr = ipc_ptr;
ESIF_TRACE_DYN_IPC("%s: START ipc %p\n", ESIF_FUNC, ipc_ptr);
/*
* If we got this far we are guaranteed to have a valid IPC
* header now we need to check to see if we hav enough data
* for the type specified if so process it if not return to
* avoid what would surely result in undesired behavior.
*/
switch (ipc_ptr->type) {
/* Command e.g. Get Participants, Etc. */
case ESIF_IPC_TYPE_COMMAND:
ESIF_TRACE_DYN_IPC("%s: COMMAND Received\n", ESIF_FUNC);
if (ipc_ptr->data_len < sizeof(struct esif_ipc_command))
ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID;
else
ipc_ret_ptr = esif_execute_ipc_command(ipc_ptr);
break;
/* Retireve A Signaled Event Or Check Event Queue */
case ESIF_IPC_TYPE_EVENT:
ESIF_TRACE_DYN_IPC("%s: EVENT Received\n", ESIF_FUNC);
if (ipc_ptr->data_len < sizeof(struct esif_ipc_event_header))
ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID;
else
ipc_ret_ptr = esif_event_queue_pull();
break;
/* Execute Primitive e.g. GET_TEMPERATURE */
case ESIF_IPC_TYPE_PRIMITIVE:
ESIF_TRACE_DYN_IPC("%s: PRIMITIVE Received\n", ESIF_FUNC);
if (ipc_ptr->data_len < sizeof(struct esif_ipc_primitive))
ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID;
else
ipc_ret_ptr = esif_execute_ipc_primitive(ipc_ptr);
break;
/* NOOP For Testing */
case ESIF_IPC_TYPE_NOOP:
ESIF_TRACE_DYN_IPC("%s: NOOP Received\n", ESIF_FUNC);
ipc_ret_ptr = NULL;
break;
/* Unsupported or Unknown IPC Type Received */
default:
ESIF_TRACE_DYN_IPC("%s: Unknown IPC Type Received type=%u\n",
ESIF_FUNC,
ipc_ptr->type);
ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID;
break;
}
ESIF_TRACE_DYN_IPC("%s: FINISH return result: %s(%u)\n",
ESIF_FUNC,
esif_rc_str(ipc_ptr->return_code),
ipc_ptr->return_code);
return ipc_ret_ptr;
}
/* Init */
enum esif_rc esif_ipc_init(
esif_device_t device
)
{
ESIF_TRACE_DYN_INIT("%s: Initialize IPC\n", ESIF_FUNC);
return esif_os_ipc_init(device);
}
/* Exit */
void esif_ipc_exit(
esif_device_t device
)
{
esif_os_ipc_exit(device);
ESIF_TRACE_DYN_INIT("%s: Exit IPC\n", ESIF_FUNC);
}
#endif /* ESIF_ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
/*
** User Implementation
*/
/* IPC Connect */
esif_handle_t esif_ipc_connect(
esif_string session_id
)
{
ESIF_TRACE_DEBUG("%s: IPC session_id = %s\n",
ESIF_FUNC, session_id);
return esif_os_ipc_connect(session_id);
}
/* IPC Disconnect */
void esif_ipc_disconnect(
esif_handle_t handle
)
{
ESIF_TRACE_DEBUG("%s: IPC handle = %d\n",
ESIF_FUNC, handle);
esif_os_ipc_disconnect(handle);
}
/* IPC Execute */
enum esif_rc esif_ipc_execute(
esif_handle_t handle,
struct esif_ipc *ipc_ptr
)
{
ESIF_TRACE_DEBUG("%s: handle = %d, IPC = %p\n",
ESIF_FUNC, handle, ipc_ptr);
return esif_os_ipc_execute(handle, ipc_ptr);
}
#endif /* ESIF_ATTR_USER */
/*
** Agnostic Implementation
*/
/* Allocate IPC */
struct esif_ipc *esif_ipc_alloc(
enum esif_ipc_type type,
u32 data_len
)
{
u32 ipc_size = data_len + sizeof(struct esif_ipc);
struct esif_ipc *ipc_ptr = (struct esif_ipc *)esif_ccb_malloc(ipc_size);
if (NULL == ipc_ptr)
return NULL;
ipc_ptr->version = ESIF_IPC_VERSION;
ipc_ptr->type = type;
ipc_ptr->data_len = data_len;
ipc_ptr->return_code = ESIF_OK;
#ifdef ESIF_ATTR_HMAC
esif_ccb_memcpy(ipc->hmac, x, ESIF_HMAC_LEN);
#endif
ESIF_TRACE_DEBUG("%s: ipc = %p, type = %d, size = %d data_len = %d\n",
ESIF_FUNC, ipc_ptr, type, (int)ipc_size,
(int)data_len);
return ipc_ptr;
}
/* Allocate Command IPC */
struct esif_ipc *esif_ipc_alloc_command(
struct esif_ipc_command **command_ptr_ptr,
u32 data_len
)
{
struct esif_ipc *ipc_ptr = NULL;
ipc_ptr = esif_ipc_alloc(ESIF_IPC_TYPE_COMMAND,
data_len + sizeof(struct esif_ipc_command));
if (NULL == ipc_ptr) {
*command_ptr_ptr = NULL;
} else {
struct esif_ipc_command *command_ptr = NULL;
command_ptr = (struct esif_ipc_command *)(ipc_ptr + 1);
command_ptr->version = ESIF_COMMAND_VERSION;
command_ptr->priority = ESIF_COMMAND_PRIORITY_NORMAL;
command_ptr->payload_len = data_len;
*command_ptr_ptr = command_ptr;
}
return ipc_ptr;
}
/* Allocate Primitive IPC */
struct esif_ipc *esif_ipc_alloc_primitive(
struct esif_ipc_primitive **primitive_ptr_ptr,
u32 data_len
)
{
struct esif_ipc *ipc_ptr = NULL;
ipc_ptr = esif_ipc_alloc(ESIF_IPC_TYPE_PRIMITIVE,
data_len + sizeof(struct esif_ipc_primitive));
if (NULL == ipc_ptr) {
*primitive_ptr_ptr = NULL;
} else {
struct esif_ipc_primitive *primitive_ptr = NULL;
primitive_ptr = (struct esif_ipc_primitive *)(ipc_ptr + 1);
primitive_ptr->version = ESIF_PRIMITIVE_VERSION;
primitive_ptr->payload_len = data_len;
*primitive_ptr_ptr = primitive_ptr;
}
return ipc_ptr;
}
/* Free IPC */
void esif_ipc_free(struct esif_ipc *ipc_ptr)
{
ESIF_TRACE_DEBUG("%s: ipc = %p\n", ESIF_FUNC, ipc_ptr);
esif_ccb_free(ipc_ptr);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,313 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_IPC_H_
#define _ESIF_IPC_H_
/*
** User Decleration
*/
/*
** Agnostic Decleration
*/
#include "esif.h"
#include "esif_pm.h"
#include "esif_command.h"
#define IPC_DEVICE "esif_lf"
/* IOCTLS May There Be Few */
#ifdef ESIF_ATTR_OS_LINUX
#define ESIF_IOCTL_IPC_NOOP _IO('A', 0)
#define ESIF_IOCTL_IPC _IOWR('A', 1, u8*)
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
#define ESIF_IPC_CODE(x) CTL_CODE(FILE_DEVICE_NETWORK, x, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define ESIF_IOCTL_IPC_NOOP ESIF_IPC_CODE(0)
#define ESIF_IOCTL_IPC ESIF_IPC_CODE(1)
#define ESIF_IOCTL_IPC_IPC_SUSPEND ESIF_IPC_CODE(2)
#define ESIF_IOCTL_IPC_IPC_RESUME ESIF_IPC_CODE(3)
#endif
/* IPC Types May There Be Few */
enum esif_ipc_type {
ESIF_IPC_TYPE_PRIMITIVE,/* ESIF Primitive */
ESIF_IPC_TYPE_EVENT, /* ESIF Event */
ESIF_IPC_TYPE_COMMAND, /* ESIF Command */
ESIF_IPC_TYPE_NOOP, /* No Operation For Test */
ESIF_IPC_TYPE_MAX
};
/* OS Agnostic ESIF IPC */
#define ESIF_HMAC_LEN 20
#define ESIF_IPC_VERSION 1
/*
* IPC
*/
/* USE Native Data Types With Packed Structures */
#pragma pack(push, 1)
struct esif_ipc {
u8 version; /* Version Of IPC */
#ifdef ESIF_ATTR_HMAC
u8 hmac[ESIF_HMAC_LEN];/* Optional HMAC Authentication If Any */
#endif
enum esif_ipc_type type; /* Type Of IPC */
u32 data_len; /* Data Length */
enum esif_rc return_code; /* Result Of Primitive Execution */
/* Data Is Here ... */
};
#pragma pack(pop)
#ifdef ESIF_ATTR_USER
typedef struct esif_ipc EsifIpc, *EsifIpcPtr, **EsifIpcPtrLocation;
#endif
/*
* IPC Primitive
*/
/* USE Native Data Types With Packed Structures */
#pragma pack(push, 1)
struct esif_ipc_primitive {
u8 version; /* Version Of Primitive IPC */
u32 id; /* Primitive ID*/
u16 domain; /* Primitive Domain e.g. CPU, GFX, Etc.*/
u8 instance; /* Instance e.g. _AC0, _AC1, Etc. */
u8 src_id; /* Source Of Primitive */
u8 dst_id; /* Destination Of Primitive UCAST, MCAST, BCAST */
enum esif_rc return_code; /* Result Of Primitive Execution */
u16 kern_action; /* i-th Kernel Action To Run */
enum esif_action_type action_type; /* Request Action Type Or LF Execute All */
u32 payload_len; /* Payload Length */
enum esif_data_type req_data_type; /* Request Data Type */
u32 req_data_offset; /* Start Of Request Data Usually Zero */
u32 req_data_len; /* Length Of Request Data May Be Zero No Data */
enum esif_data_type rsp_data_type; /* Respond Data Type */
u32 rsp_data_offset; /* Respond Data Offset */
u32 rsp_data_len; /* Respond Data Length */
/* Data Is Here ... */
};
#pragma pack(pop)
#ifdef ESIF_ATTR_USER
typedef struct esif_ipc_primitive EsifIpcPrimitive, *EsifIpcPrimitivePtr,
**EsifPrimitivePtrLoction;
#endif
/* Primitive Source Is Always Upper Framework Or UNICAST */
static ESIF_INLINE esif_string esif_primitive_src_str (u8 src_id)
{
if (ESIF_INSTANCE_UF == src_id)
return (esif_string)"ESIF_UF";
return (esif_string)"UNICAST";
}
/* Privite Destination Can Be UNICAST, MULTICAST Or BROADCAST */
static ESIF_INLINE esif_string esif_primitive_dst_str (u8 dst_id)
{
if (ESIF_INSTANCE_BROADCAST == dst_id) {
return (esif_string)"BROADCAST";
} else {
if (dst_id < 100)
return (esif_string)"UNICAST";
else
return (esif_string)"MULTICAST";
}
}
/*
* IPC Event
*/
/* USE Native Data Types With Packed Structures */
#pragma pack(push, 1)
struct esif_ipc_event_header {
u8 version; /* Version Of Primitive Event */
enum esif_event_type type; /* Event Type */
u64 id; /* Event Transaction ID */
u64 timestamp; /* Event Timestamp In msec */
enum esif_event_priority priority; /* Event Priority */
u8 src_id; /* Source Of Event */
u8 dst_id; /* Dest Of Event */
u16 dst_domain_id; /* Destination Domain ID */
u32 data_len; /* Data Length May Be Zero */
/* Data Is Here ... */
};
#pragma pack(pop)
/*
** IPC Event Create Participant Data. Will be tacked on the bottom
** of an IPC Event for participant creation. Note the IPC event and
** This data must be contiguous in memory space.
*/
/* USE Native Data Types With Packed Structures */
#pragma pack(push, 1)
struct esif_ipc_event_data_create_participant {
u8 id; /* Participant ID */
u8 version; /* Version */
u8 class_guid[ESIF_GUID_LEN]; /* Class GUID */
enum esif_participant_enum enumerator; /* Device Enumerator If Any */
u32 flags; /* Flags If Any */
char name[ESIF_NAME_LEN]; /* Friendly Name */
char desc[ESIF_DESC_LEN]; /* Description */
char driver_name[ESIF_NAME_LEN]; /* Driver Name */
char device_name[ESIF_NAME_LEN]; /* Device Name */
char device_path[ESIF_PATH_LEN]; /* Device Path */
char acpi_device[ESIF_SCOPE_LEN]; /* Scope/REGEX e.g. \_SB.PCI0.TPCH */
char acpi_scope[ESIF_SCOPE_LEN]; /* Scope/REGEX e.g. \_SB.PCI0.TPCH */
char acpi_uid[ESIF_ACPI_UID_LEN]; /* Unique ID If Any */
u32 acpi_type; /* Participant Type If Any */
u32 pci_vendor; /* PCI Vendor For PCI Devices */
u32 pci_device; /* PCE Device For PCI Devices */
u8 pci_bus; /* Bus Device Was Enumerated On */
u8 pci_bus_device; /* Device Number On Bus */
u8 pci_function; /* PCI Function Of Device */
u8 pci_revision; /* PCI Hardware Revision */
u8 pci_class; /* PCI Hardware Class */
u8 pci_sub_class; /* PCI Hardware Sub Class */
u8 pci_prog_if; /* PCI Hardware Iface */
};
#pragma pack(pop)
/*
* IPC Command
*/
/* USE Native Data Types With Packed Structures */
#pragma pack(push, 1)
struct esif_ipc_command {
u8 version; /* Version Of Primitive Event */
enum esif_command_type type; /* Command Type */
enum esif_command_priority priority; /* Event Priority */
enum esif_rc return_code; /* Result Of Primitive Execution */
u32 payload_len; /* Payload Length */
enum esif_data_type req_data_type; /* Request Data Type */
u32 req_data_offset; /* Start Of Request Data Usually Zero */
u32 req_data_len; /* Length Of Request Data May Be 0 (None) */
enum esif_data_type rsp_data_type; /* Request Data Type */
u32 rsp_data_offset; /* Request Data Offset */
u32 rsp_data_len; /* Request Data Length */
};
#pragma pack(pop)
/* IPC Allocation */
#ifdef __cplusplus
extern "C" {
#endif
struct esif_ipc *esif_ipc_alloc(enum esif_ipc_type type, u32 dataLen);
struct esif_ipc *esif_ipc_alloc_command(
struct esif_ipc_command **command_ptr_ptr,
u32 data_len);
struct esif_ipc *esif_ipc_alloc_primitive(
struct esif_ipc_primitive **primitive_ptr_ptr,
u32 data_len);
void esif_ipc_free(struct esif_ipc *ipc_ptr);
esif_handle_t esif_ipc_connect(char *session_id);
void esif_ipc_disconnect(esif_handle_t handle);
enum esif_rc esif_ipc_execute(esif_handle_t handle, struct esif_ipc *ipc_ptr);
/* IPC Connect */
esif_handle_t esif_os_ipc_connect(char *session_id);
/* IPC Disconnect */
void esif_os_ipc_disconnect(esif_handle_t handle);
/* IPC Execute */
enum esif_rc esif_os_ipc_execute(esif_handle_t handle,
struct esif_ipc *ipc_ptr);
#ifdef __cplusplus
}
#endif
#ifdef ESIF_ATTR_KERNEL
/*
* Kernel Decleration
*/
/* Receive IPC */
struct esif_ipc *esif_ipc_process(struct esif_ipc *ipc_ptr);
/* Init / Exit */
enum esif_rc esif_ipc_init(esif_device_t device);
enum esif_rc esif_os_ipc_init(esif_device_t device);
void esif_ipc_exit(esif_device_t device);
void esif_os_ipc_exit(esif_device_t device);
#endif /* ESIF_ATTR_KERNEL */
#endif /* _ESIF_IPC_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,469 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifdef ESIF_ATTR_USER
# define ESIF_TRACE_DEBUG_DISABLED
#endif
#include "esif.h"
#include "esif_ipc.h"
#ifdef ESIF_ATTR_KERNEL
#include <linux/miscdevice.h> /* Linux /dev/esif MISC Device */
#include <linux/poll.h> /* Linux Polling Support */
/* Debug Logging Defintions */
#define ESIF_DEBUG_MODULE ESIF_DEBUG_MOD_LINUX
#define INIT_DEBUG 0 /* this */
#define IPC_DEBUG 1 /* this */
#define IPC_POLL 2 /* this */
#define RESERVED4 3 /* this */
#define RESERVED8 4 /* esif_ipc.c */
#define RESERVED10 5 /* esif_ipc.c */
#define RESERVED20 6 /* esif_ipc.c */
#define RESERVED40 7 /* esif_ipc.c */
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_IPC, INIT_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_IPC(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_IPC, IPC_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_IPC_POLL(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_IPC, IPC_POLL, format, ##__VA_ARGS__)
/*
******************************************************************************
* PRIVATE
******************************************************************************
*/
/* Translate User Space IPC to Kernel */
static struct esif_ipc *esif_ipc_user_to_kernel(struct esif_ipc *ipc_user_ptr)
{
int ipc_len = 0;
struct esif_ipc ipc_hdr = {0};
struct esif_ipc *ipc_ptr = NULL;
if (NULL == ipc_user_ptr)
return NULL;
/* Copy from user an error indicates how many bytes copied. */
if (copy_from_user(&ipc_hdr, ipc_user_ptr,
sizeof(struct esif_ipc)) > 0) {
return NULL;
}
/* Sanity Check */
if (ESIF_IPC_VERSION != ipc_hdr.version)
return NULL;
ESIF_TRACE_DYN_IPC(
"linux_%s: ipc version=%d, type=%d, data_len=%d, rc=%d\n",
__func__,
ipc_hdr.version,
ipc_hdr.type,
(int)ipc_hdr.data_len,
(int)ipc_hdr.return_code);
ipc_len = ipc_hdr.data_len + sizeof(struct esif_ipc);
ipc_ptr = esif_ccb_malloc(ipc_len);
if (NULL == ipc_ptr)
return NULL;
/* Copy from user an error indicates how many bytes copied. */
if (copy_from_user(ipc_ptr, ipc_user_ptr, ipc_len) > 0) {
esif_ccb_free(ipc_ptr);
return NULL;
}
return ipc_ptr;
}
/* Translate Kernel IPC To User Space */
static int esif_ipc_kernel_to_user(
struct esif_ipc *ipc_user_ptr,
struct esif_ipc *ipc_kernel_ptr
)
{
u32 len = 0;
if (NULL == ipc_user_ptr || NULL == ipc_kernel_ptr)
return -EINVAL;
len = ipc_kernel_ptr->data_len + sizeof(struct esif_ipc);
ESIF_TRACE_DYN_IPC(
"linux_%s: ipc version=%d, type=%d, len = %d, "
"data_len=%d, rc=%d\n",
__func__,
ipc_kernel_ptr->version,
ipc_kernel_ptr->type,
(int)len,
(int)ipc_kernel_ptr->data_len,
ipc_kernel_ptr->return_code);
/* TODO Check For Fit When Possible */
if (copy_to_user(ipc_user_ptr, ipc_kernel_ptr, len) > 0)
return -ENOMEM;
return len;
}
/* IOCTL */
static int esif_ipc_ioctl(struct esif_ipc *ipc_user_ptr)
{
int rc = 0;
struct esif_ipc *ipc_req_ptr = esif_ipc_user_to_kernel(ipc_user_ptr);
struct esif_ipc *ipc_rsp_ptr = NULL;
if (NULL == ipc_req_ptr)
return -ENOMEM;
ESIF_TRACE_DYN_IPC("linux_%s: user %p kernel %p\n",
__func__,
ipc_user_ptr,
ipc_req_ptr);
ipc_rsp_ptr = esif_ipc_process(ipc_req_ptr);
if (NULL != ipc_rsp_ptr) {
esif_ipc_kernel_to_user((struct esif_ipc *)ipc_user_ptr,
ipc_rsp_ptr);
ESIF_TRACE_DYN_IPC("linux_%s: user %p kernel %p\n",
__func__,
ipc_user_ptr,
ipc_rsp_ptr);
if (ipc_req_ptr != ipc_rsp_ptr)
esif_ipc_free(ipc_rsp_ptr);
} else {
rc = -EINVAL;
}
esif_ccb_free(ipc_req_ptr);
return rc;
}
/* IOCTL Operation */
static long esif_ioctl(
struct file *filp_ptr,
u_int cmd,
u_long arg
)
{
int rc = -EINVAL;
ESIF_TRACE_DYN_IPC("linux_%s: ioctl cmd %x\n", __func__, cmd);
switch (cmd) {
case ESIF_IOCTL_IPC_NOOP:
ESIF_TRACE_DYN_IPC("linux_%s: NOOP cmd=%x\n", __func__, cmd);
break;
case ESIF_IOCTL_IPC:
ESIF_TRACE_DYN_IPC("linux_%s: ESIF_IOCTL_IPC\n", __func__);
rc = esif_ipc_ioctl((struct esif_ipc *)arg);
break;
default:
ESIF_TRACE_DYN_IPC("linux_%s: NOT IMPLEMENTED %x\n",
__func__,
cmd);
break;
}
return rc;
}
/*
** File Operations
*/
static DECLARE_WAIT_QUEUE_HEAD(esif_waitqueue);
/* IOCTL */
static ssize_t esif_file_ipc(
struct file *fp,
char __user *buf,
size_t count,
loff_t *ppos
)
{
u32 len = 0;
struct esif_ipc *ipc_req_ptr = esif_ipc_user_to_kernel(
(struct esif_ipc *)buf);
struct esif_ipc *ipc_rsp_ptr = NULL;
if (count < sizeof(struct esif_ipc))
return -EINVAL;
if (NULL == ipc_req_ptr)
return -ENOMEM;
ESIF_TRACE_DYN_IPC("linux_%s: user %p kernel %p count %d\n",
__func__, buf, ipc_req_ptr, (int)count);
ipc_rsp_ptr = esif_ipc_process(ipc_req_ptr);
if (NULL != ipc_rsp_ptr) {
len = esif_ipc_kernel_to_user((struct esif_ipc *)buf,
ipc_rsp_ptr);
ESIF_TRACE_DYN_IPC("linux_%s: user %p kernel %p count = %d\n",
__func__, buf, ipc_rsp_ptr, (int)count);
if (ipc_req_ptr != ipc_rsp_ptr)
esif_ipc_free(ipc_rsp_ptr);
}
esif_ccb_free(ipc_req_ptr);
return len;
}
/* Read */
static ssize_t esif_read_file_ipc(
struct file *fp,
char __user *buf,
size_t count,
loff_t *ppos
)
{
return esif_file_ipc(fp, buf, count, ppos);
}
/* Write */
static ssize_t esif_write_file_ipc(
struct file *fp,
const char __user *buf,
size_t count,
loff_t *ppos
)
{
return esif_file_ipc(fp, (char __user *)buf, count, ppos);
}
/* Poll */
static unsigned int esif_poll(
struct file *fp,
poll_table * wait
)
{
ESIF_TRACE_DYN_IPC_POLL("linux_%s: POLL Event Queue\n", __func__);
poll_wait(fp, &esif_waitqueue, wait);
return esif_event_queue_size() == 0 ? 0 : POLLIN | POLLRDNORM;
}
/* Open */
static int esif_open(struct inode *inode, struct file *filp)
{
ESIF_TRACE_DYN_IPC("linux_%s: %s Device Opened\n", __func__,
IPC_DEVICE);
return 0;
}
/* Release */
static int esif_release(struct inode *inode, struct file *filp)
{
ESIF_TRACE_DYN_IPC("linux_%s: %s Device Closed\n", __func__,
IPC_DEVICE);
return 0;
}
/* Seek Not Used */
static loff_t esif_llseek(struct file *filp, loff_t a, int b)
{
return -EINVAL;
}
/* File Operations */
static const struct file_operations esif_fops = {
.owner = THIS_MODULE,
.read = esif_read_file_ipc,
.write = esif_write_file_ipc,
.poll = esif_poll,
.unlocked_ioctl = esif_ioctl,
.open = esif_open,
.release = esif_release,
.llseek = esif_llseek /* noop_llseek */
};
/* Define ESIF MISC Device */
static struct miscdevice esif_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = IPC_DEVICE,
.fops = &esif_fops
};
/*
******************************************************************************
* PUBLIC
******************************************************************************
*/
/* Init */
enum esif_rc esif_os_ipc_init(esif_device_t device)
{
int rc = 0;
ESIF_TRACE_DYN_INIT("linux_%s: Initialize IPC\n", __func__);
/* Create misc_device here */
rc = misc_register(&esif_device);
if (rc) {
dev_dbg(esif_device.this_device,
"failed to register misc dev %d\n",
rc);
return ESIF_E_UNSPECIFIED;
}
ESIF_TRACE_DYN_INIT("linux_%s: IPC Registration:\n"
" Method: IOCTL\n"
" Device: /dev/%s\n"
" Type: char\n"
" Mode: READ/WRITE\n",
__func__, IPC_DEVICE);
return ESIF_OK;
}
/* Exit */
void esif_os_ipc_exit(esif_device_t device)
{
int rc = 0;
ESIF_TRACE_DYN_INIT("linux_%s: Exit IPC\n", __func__);
rc = misc_deregister(&esif_device);
if (rc) {
dev_dbg(esif_device.this_device,
"failed to unregister misc dev %d\n",
rc);
}
ESIF_TRACE_DYN_INIT("linux_%s: IOCTL Device %s UnRegistered\n",
__func__,
IPC_DEVICE);
}
#endif /* ESIF_ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
/*
******************************************************************************
* User
******************************************************************************
*/
/* IPC OS Connect */
esif_handle_t esif_os_ipc_connect(char *session_id)
{
int fd = 0;
char device[64];/* Jacob Is There a Standard Path Length? */
sprintf(device, "/dev/%s", IPC_DEVICE);
fd = open(device, O_RDWR);
ESIF_TRACE_DEBUG("linux_%s: session_id=%s device=%s handle=%d\n",
__func__, session_id, device, fd);
return fd;
}
/* IPC OS Disconnect */
void esif_os_ipc_disconnect(esif_handle_t handle)
{
ESIF_TRACE_DEBUG("linux_%s: IPC handle = %d\n", __func__, handle);
close(handle);
}
/* IPC OS Execution */
enum esif_rc esif_os_ipc_execute(
esif_handle_t handle,
struct esif_ipc *ipc_ptr
)
{
int rc = 0;
ESIF_TRACE_DEBUG("linux_%s: handle = %d, IPC = %p\n",
__func__,
handle,
ipc_ptr);
/* use IOCTL or read here */
#ifdef ESIF_ATTR_OS_ANDROID
rc = read(handle, ipc_ptr, ipc_ptr->data_len + sizeof(struct esif_ipc));
ESIF_TRACE_DEBUG("linux_%s: READ handle = %d, IPC = %p rc = %d\n",
__func__, handle, ipc_ptr, rc);
#else
rc = ioctl(handle, ESIF_IOCTL_IPC, ipc_ptr);
ESIF_TRACE_DEBUG("linux_%s: IOCTL handle = %d, IPC = %p rc = %d\n",
__func__, handle, ipc_ptr, rc);
if (rc)
return ESIF_E_UNSPECIFIED;
#endif
return ESIF_OK;
}
#endif /* ESIF_ATTR_USER */
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,110 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_LF_H_
#define _ESIF_LF_H_
#include "esif.h"
#include "esif_participant.h"
/* Registration */
enum esif_rc esif_lf_register_participant(struct esif_participant_iface *pi_ptr);
void esif_lf_unregister_all_participants(void);
enum esif_rc esif_lf_unregister_participant(
struct esif_participant_iface *pi_ptr);
/* Instrumentation */
enum esif_rc esif_lf_instrument_participant(struct esif_lp *lp_ptr);
enum esif_rc esif_lf_instrument_capability(struct esif_lp_domain *lpd_ptr);
void esif_lf_uninstrument_participant(struct esif_lp *lp_ptr);
void esif_lf_uninstrument_capability(struct esif_lp_domain *lpd_ptr);
/* Events */
enum esif_rc esif_lf_event(
struct esif_participant_iface *pi_ptr,
enum esif_event_type type,
u16 domain,
struct esif_data *data_ptr
);
enum esif_rc esif_lf_send_event(
const struct esif_participant_iface *pi_ptr,
const struct esif_event *event_ptr
);
enum esif_rc esif_lf_send_all_events_in_queue_to_uf_by_ipc(void);
/* Init / Exit */
enum esif_rc esif_lf_init(esif_flags_t debug_mask);
void esif_lf_exit(void);
/* Optional OS Init/Exit. Call before esif_ccb_malloc & after esif_ccb_free */
void esif_lf_os_init(void);
void esif_lf_os_exit(void);
enum esif_rc esif_execute_xform_func(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const enum esif_action_type action,
const enum esif_data_type data_type,
u64 *temp_ptr
);
#endif /* _ESIF_LF_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,636 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_lf_action.h"
#include "esif_participant.h"
#include "esif_lf_ccb_gen_action.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified against Windows SDK/DDK included headers which
* we have no control over.
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
/* Debug Logging Defintions */
#define INIT_DEBUG 0 /* Init Debug */
#define ACTION_DEBUG 1 /* Primitive Debug */
#define DECODE_DEBUG 2 /* Decode Debug */
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION, \
INIT_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_ACTION(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION, \
ACTION_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_DECODE(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION, \
DECODE_DEBUG, format, ##__VA_ARGS__)
/* Execute Action */
enum esif_rc esif_execute_action(
struct esif_lp *lp_ptr,
struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr
)
{
enum esif_rc rc = ESIF_OK;
esif_temp_t orig_temp = 0;
u8 was_temp = ESIF_FALSE;
u8 was_power = ESIF_FALSE;
u8 was_percent = ESIF_FALSE;
enum esif_data_type rsp_xform_type = 0;
if ((NULL == lp_ptr) || (NULL == primitive_ptr) ||
(NULL == action_ptr) || (NULL == req_data_ptr) ||
(NULL == rsp_data_ptr)) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
ESIF_TRACE_DYN_ACTION(
"---->LF ACTION: Type = %s, Opcode = %s Tuple = %d.%d.%d\n",
esif_action_type_str(action_ptr->type),
esif_primitive_opcode_str(primitive_ptr->opcode),
primitive_ptr->tuple.id,
primitive_ptr->tuple.domain,
primitive_ptr->tuple.instance);
ESIF_TRACE_DYN_ACTION(
"LP Name = %s, req_type = %s, rsp_type = %s\n",
lp_ptr->pi_name,
esif_data_type_str(req_data_ptr->type),
esif_data_type_str(rsp_data_ptr->type));
/*
* If it is a s SET request and we have a valide temp or power xform,
* normalize the requested tmperature (_t) and power (_pw) in the
* request.
*/
if (primitive_ptr->opcode == ESIF_PRIMITIVE_OP_SET) {
/* Unnormalize Temperature Example C -> Deci Kelvin */
if (req_data_ptr->type == ESIF_DATA_TEMPERATURE) {
orig_temp = *(u32 *)req_data_ptr->buf_ptr;
rc = esif_execute_xform_func(lp_ptr,
primitive_ptr,
action_ptr->type,
ESIF_DATA_TEMPERATURE,
(u64 *)req_data_ptr->buf_ptr);
if (rc != ESIF_OK)
goto exit;
}
/* Unnormalize Power Example Milliwatts -> Deci Watts*/
if (req_data_ptr->type == ESIF_DATA_POWER) {
rc = esif_execute_xform_func(lp_ptr,
primitive_ptr,
action_ptr->type,
ESIF_DATA_POWER,
(u64 *) req_data_ptr->buf_ptr);
if (rc != ESIF_OK)
goto exit;
}
}
/*
* Okay If we have gotten here we have a DSP and have found our
* primitive so now we will execute the primitive based on the
* request and the DSP Metadata.
*/
/* Transform data type for temp into native UINT32 data type for NOW */
if (ESIF_PRIMITIVE_OP_GET == primitive_ptr->opcode &&
ESIF_DATA_TEMPERATURE == rsp_data_ptr->type) {
ESIF_TRACE_DYN_ACTION("CHANGE RSP TEMPERATURE >> UINT32\n");
rsp_data_ptr->type = ESIF_DATA_UINT32;
was_temp = ESIF_TRUE;
}
/* Transform data type for power into native UINT32 data type for NOW */
if (ESIF_PRIMITIVE_OP_GET == primitive_ptr->opcode &&
ESIF_DATA_POWER == rsp_data_ptr->type) {
ESIF_TRACE_DYN_ACTION("CHANGE RSP POWER >> UINT32\n");
rsp_data_ptr->type = ESIF_DATA_UINT32;
was_power = ESIF_TRUE;
}
/* Transform data type for temp into native UINT32 data type for NOW */
if (ESIF_PRIMITIVE_OP_SET == primitive_ptr->opcode &&
ESIF_DATA_TEMPERATURE == req_data_ptr->type) {
ESIF_TRACE_DYN_ACTION("CHANGE REQ TEMPERATURE >> UINT32\n");
req_data_ptr->type = ESIF_DATA_UINT32;
was_temp = ESIF_TRUE;
}
/* Transform data type for power into native UINT32 data type for NOW */
if (ESIF_PRIMITIVE_OP_SET == primitive_ptr->opcode &&
ESIF_DATA_POWER == req_data_ptr->type) {
ESIF_TRACE_DYN_ACTION("CHANGE REQ POWER >> UINT32\n");
req_data_ptr->type = ESIF_DATA_UINT32;
was_power = ESIF_TRUE;
}
if ((ESIF_PRIMITIVE_OP_GET == primitive_ptr->opcode) &&
(ESIF_DATA_PERCENT == rsp_data_ptr->type)) {
was_percent = ESIF_TRUE;
rsp_data_ptr->type = ESIF_DATA_UINT32;
}
if ((ESIF_PRIMITIVE_OP_SET == primitive_ptr->opcode) &&
(ESIF_DATA_PERCENT == req_data_ptr->type)) {
was_percent = ESIF_TRUE;
*(u32 *)req_data_ptr->buf_ptr /= ESIF_PERCENT_CONV_FACTOR;
req_data_ptr->type = ESIF_DATA_UINT32;
}
/* Handle Actions */
switch (action_ptr->type) {
case ESIF_ACTION_ACPI:
{
switch (primitive_ptr->opcode) {
case ESIF_PRIMITIVE_OP_GET:
rc = esif_get_action_acpi(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr,
rsp_data_ptr);
break;
case ESIF_PRIMITIVE_OP_SET:
rc = esif_set_action_acpi(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr);
break;
default:
rc = ESIF_E_OPCODE_NOT_IMPLEMENTED;
break;
}
}
break; /* End of ACPI */
/*
* Handle ACPI LPAT Actions
*/
case ESIF_ACTION_ACPILPAT:
{
rsp_data_ptr->data_len = sizeof(u32);
/* Fake Data Example 596 -> ~32C */
/* ((u32 *)rsp_data_ptr->buf_ptr) = 596; */
switch (primitive_ptr->opcode) {
case ESIF_PRIMITIVE_OP_GET:
rc = esif_get_action_acpi(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr,
rsp_data_ptr);
break;
default:
rc = ESIF_E_OPCODE_NOT_IMPLEMENTED;
break;
}
}
break; /* End of ACPILPAT */
/*
* Handle Constant Actions
*/
case ESIF_ACTION_KONST:
{
switch (primitive_ptr->opcode) {
case ESIF_PRIMITIVE_OP_GET:
rc = esif_get_action_const(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr,
rsp_data_ptr);
break;
case ESIF_PRIMITIVE_OP_SET:
default:
rc = ESIF_E_OPCODE_NOT_IMPLEMENTED;
break;
}
}
break; /* End of CONST */
/*
* Handle CODE Actions
*/
case ESIF_ACTION_KODE:
{
switch (primitive_ptr->opcode) {
case ESIF_PRIMITIVE_OP_GET:
rc = esif_get_action_code(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr,
rsp_data_ptr);
break;
case ESIF_PRIMITIVE_OP_SET:
rc = esif_set_action_code(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr);
break;
default:
rc = ESIF_E_OPCODE_NOT_IMPLEMENTED;
break;
}
}
break; /* End of CODE */
/*
* Handle SYSTEMIO Actions
*/
case ESIF_ACTION_SYSTEMIO:
{
switch (primitive_ptr->opcode) {
case ESIF_PRIMITIVE_OP_GET:
rc = esif_get_action_systemio(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr,
rsp_data_ptr);
break;
case ESIF_PRIMITIVE_OP_SET:
rc = esif_set_action_systemio(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr);
break;
default:
rc = ESIF_E_OPCODE_NOT_IMPLEMENTED;
break;
}
}
break; /* End of SYSTEMIO */
/*
* Handle VAR Actions
*/
case ESIF_ACTION_VAR:
{
switch (primitive_ptr->opcode) {
case ESIF_PRIMITIVE_OP_GET:
rc = esif_get_action_var(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr,
rsp_data_ptr);
break;
case ESIF_PRIMITIVE_OP_SET:
rc = esif_set_action_var(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr);
break;
default:
rc = ESIF_E_OPCODE_NOT_IMPLEMENTED;
break;
}
}
break; /* End of VAR */
/*
* Handle MBI Actions
*/
case ESIF_ACTION_IOSF:
{
switch (primitive_ptr->opcode) {
case ESIF_PRIMITIVE_OP_GET:
rc = esif_get_action_mbi(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr,
rsp_data_ptr);
break;
case ESIF_PRIMITIVE_OP_SET:
rc = esif_set_action_mbi(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr);
break;
default:
rc = ESIF_E_OPCODE_NOT_IMPLEMENTED;
break;
}
}
break; /* End of MBI */
/*
* Handle MMIO Actions
*/
case ESIF_ACTION_MMIO:
case ESIF_ACTION_MMIOTJMAX:
{
switch (primitive_ptr->opcode) {
case ESIF_PRIMITIVE_OP_GET:
rc = esif_get_action_mmio(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr,
rsp_data_ptr);
break;
case ESIF_PRIMITIVE_OP_SET:
rc = esif_set_action_mmio(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr);
break;
default:
rc = ESIF_E_OPCODE_NOT_IMPLEMENTED;
break;
}
}
break; /* End of MMIO */
/*
* Handle MSR Actions
*/
case ESIF_ACTION_MSR:
{
switch (primitive_ptr->opcode) {
case ESIF_PRIMITIVE_OP_GET:
/* Keep original respond type needed by msr action */
if (ESIF_TRUE == was_temp)
rsp_xform_type = ESIF_DATA_TEMPERATURE;
else if (ESIF_TRUE == was_power)
rsp_xform_type = ESIF_DATA_POWER;
else
rsp_xform_type = rsp_data_ptr->type;
rc = esif_get_action_msr(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr,
rsp_xform_type,
rsp_data_ptr);
break;
case ESIF_PRIMITIVE_OP_SET:
rc = esif_set_action_msr(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr);
break;
default:
rc = ESIF_E_OPCODE_NOT_IMPLEMENTED;
break;
}
}
break; /* End of MSR */
/*
* Handle DDIGFXPERF Actions
*/
case ESIF_ACTION_DDIGFXPERF:
{
switch (primitive_ptr->opcode) {
case ESIF_PRIMITIVE_OP_GET:
rc = esif_get_action_ddigfxperf(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr,
rsp_data_ptr);
break;
case ESIF_PRIMITIVE_OP_SET:
rc = esif_set_action_ddigfxperf(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr);
break;
default:
rc = ESIF_E_OPCODE_NOT_IMPLEMENTED;
break;
}
}
break; /* End of DDIGFXPERF */
/*
* Handle DDIGFXDISP Actions
*/
case ESIF_ACTION_DDIGFXDISP:
{
switch (primitive_ptr->opcode) {
case ESIF_PRIMITIVE_OP_GET:
rc = esif_get_action_ddigfxdisp(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr,
rsp_data_ptr);
break;
case ESIF_PRIMITIVE_OP_SET:
rc = esif_set_action_ddigfxdisp(lp_ptr,
primitive_ptr,
action_ptr,
req_data_ptr);
break;
default:
rc = ESIF_E_OPCODE_NOT_IMPLEMENTED;
break;
}
}
break; /* End of DDIGFXDISP */
default:
ESIF_TRACE_DYN_ACTION(
"prim %d NOT supported, p1 %x, result %d\n",
action_ptr->type,
action_ptr->get_p1_u32(action_ptr),
*(unsigned int *)rsp_data_ptr->buf_ptr);
rc = ESIF_E_UNSUPPORTED_ACTION_TYPE;
break;
}
/* Put back Temperature Type? */
if ((ESIF_PRIMITIVE_OP_GET == primitive_ptr->opcode) &&
(ESIF_TRUE == was_temp)) {
ESIF_TRACE_DYN_ACTION("CHANGE RSP UINT32 >> TEMPERATURE\n");
rsp_data_ptr->type = ESIF_DATA_TEMPERATURE;
}
/* Put back Power Type? */
if ((ESIF_PRIMITIVE_OP_GET == primitive_ptr->opcode) &&
(ESIF_TRUE == was_power)) {
ESIF_TRACE_DYN_ACTION("CHANGE RSP UINT32 >> POWER\n");
rsp_data_ptr->type = ESIF_DATA_POWER;
}
if ((ESIF_PRIMITIVE_OP_SET == primitive_ptr->opcode) &&
(ESIF_TRUE == was_temp)) {
ESIF_TRACE_DYN_ACTION("CHANGE REQ UINT32 >> TEMPERATURE\n");
req_data_ptr->type = ESIF_DATA_TEMPERATURE;
}
if ((ESIF_PRIMITIVE_OP_SET == primitive_ptr->opcode) &&
(ESIF_TRUE == was_power)) {
ESIF_TRACE_DYN_ACTION("CHANGE REQ UINT32 >> POWER\n");
req_data_ptr->type = ESIF_DATA_POWER;
}
if ((ESIF_PRIMITIVE_OP_GET == primitive_ptr->opcode) &&
(ESIF_TRUE == was_percent)) {
rsp_data_ptr->type = ESIF_DATA_PERCENT;
if(ESIF_OK == rc) {
*(u32 *)rsp_data_ptr->buf_ptr *=
ESIF_PERCENT_CONV_FACTOR;
}
}
if ((ESIF_PRIMITIVE_OP_SET == primitive_ptr->opcode) &&
(ESIF_TRUE == was_percent)) {
req_data_ptr->type = ESIF_DATA_PERCENT;
}
ESIF_TRACE_DYN_ACTION("LF ACTION RC (Before type conversion): %s(%d)\n",
esif_rc_str(rc), rc);
if (rc != ESIF_OK)
goto exit;
/*
* Transform temperature/power if the response type told us to do so.
*/
if (primitive_ptr->opcode == ESIF_PRIMITIVE_OP_GET) {
/* Transform Temperature */
if (rsp_data_ptr->type == ESIF_DATA_TEMPERATURE) {
rc = esif_execute_xform_func(lp_ptr,
primitive_ptr,
action_ptr->type,
ESIF_DATA_TEMPERATURE,
(u64 *) rsp_data_ptr->buf_ptr);
if (rc != ESIF_OK)
goto exit;
}
/* Transform Power */
if (rsp_data_ptr->type == ESIF_DATA_POWER) {
rc = esif_execute_xform_func(lp_ptr,
primitive_ptr,
action_ptr->type,
ESIF_DATA_POWER,
(u64 *) rsp_data_ptr->buf_ptr);
if (rc != ESIF_OK)
goto exit;
}
/*
* TODO: Inconsistent BIOS behavior here BIOS reports .1C,
* we need C
*/
if ((ESIF_ACTION_ACPI == action_ptr->type) &&
(GET_TEMPERATURE_THRESHOLD_HYSTERESIS ==
primitive_ptr->tuple.id)) {
*(u32 *)rsp_data_ptr->buf_ptr =
((*(u32 *)rsp_data_ptr->buf_ptr) / 10);
}
} else {/* ESIF_PRIMITIVE_OP_SET */
/*
* Cache aux0/aux1 temperature for devices that don't support
* GET. For SET_TEMP_THRESHOLDS and ACTION NOT Code IF ESIF_OK
*/
if ((req_data_ptr->type == ESIF_DATA_TEMPERATURE) &&
(primitive_ptr->tuple.id == SET_TEMPERATURE_THRESHOLDS) &&
(action_ptr->type != ESIF_ACTION_KODE)) {
u8 domain_index = 0;
rc = esif_lp_domain_index(primitive_ptr->tuple.domain,
&domain_index);
if ((ESIF_OK != rc) ||
(domain_index > lp_ptr->domain_count)) {
goto exit;
}
if (0 == primitive_ptr->tuple.instance)
lp_ptr->domains[domain_index].temp_cache0 =
orig_temp;
if (1 == primitive_ptr->tuple.instance)
lp_ptr->domains[domain_index].temp_cache1 =
orig_temp;
}
}
exit:
ESIF_TRACE_DYN_ACTION("<----LF ACTION FINAL RC: %s(%d)\n",
esif_rc_str(rc), rc);
return rc;
}
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,252 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_LF_ACTION_H_
#define _ESIF_LF_ACTION_H_
/* include enum esif_action_type, and lookup */
#include "esif.h"
/* Action */
struct esif_lp_action {
enum esif_action_type type; /* Execution Method For This Primitive
* */
u32 *p1_ptr; /* Parameter 1 */
u32 *p2_ptr; /* Parameter 2 */
u32 *p3_ptr; /* Parameter 3 */
u32 *p4_ptr; /* Parameter 4 */
u32 *p5_ptr; /* Parameter 5 */
enum esif_action_type (*get_type)(const struct esif_lp_action *
action_ptr);
u32 (*get_p1_u32)(const struct esif_lp_action *action_ptr);
u32 (*get_p2_u32)(const struct esif_lp_action *action_ptr);
u32 (*get_p3_u32)(const struct esif_lp_action *action_ptr);
u32 (*get_p4_u32)(const struct esif_lp_action *action_ptr);
u32 (*get_p5_u32)(const struct esif_lp_action *action_ptr);
};
/* Forward Decleration */
struct esif_lp_primitive;
struct esif_lp;
enum esif_rc esif_execute_xform_func(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const enum esif_action_type action,
const enum esif_data_type data_type,
u64 *temp_ptr
);
enum esif_rc esif_execute_action(
struct esif_lp *lp_ptr,
struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr
);
/* ACPI */
enum esif_rc esif_action_acpi_init(void);
void esif_action_acpi_exit(void);
enum esif_rc esif_get_action_acpi(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr
);
enum esif_rc esif_set_action_acpi(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr
);
/* CONSTANT */
enum esif_rc esif_action_const_init(void);
void esif_action_const_exit(void);
enum esif_rc esif_get_action_const(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr
);
/* CODE */
struct esif_primitive_tuple;
enum esif_rc esif_action_code_init(void);
void esif_action_code_exit(void);
enum esif_rc esif_get_action_code(
struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr
);
enum esif_rc esif_set_action_code(
struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr
);
/* MBI */
enum esif_rc esif_action_mbi_init(void);
void esif_action_mbi_exit(void);
enum esif_rc esif_get_action_mbi(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr
);
enum esif_rc esif_set_action_mbi(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr
);
/* MMIO */
enum esif_rc esif_action_mmio_init(void);
void esif_action_mmio_exit(void);
enum esif_rc esif_get_action_mmio(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr
);
enum esif_rc esif_set_action_mmio(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr
);
/* MSR */
enum esif_rc esif_action_msr_init(void);
void esif_action_msr_exit(void);
enum esif_rc esif_get_action_msr(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
const struct esif_data *req_data_ptr,
const enum esif_data_type xform_type,
struct esif_data *rsp_data_ptr
);
enum esif_rc esif_set_action_msr(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr
);
/* VAR */
enum esif_rc esif_action_var_init(void);
void esif_action_var_exit(void);
enum esif_rc esif_get_action_var(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr
);
enum esif_rc esif_set_action_var(
const struct esif_lp *lp_ptr,
struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr
);
/* SYSTEM IO */
enum esif_rc esif_action_systemio_init(void);
void esif_action_systemio_exit(void);
enum esif_rc esif_get_action_systemio(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr
);
enum esif_rc esif_set_action_systemio(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr
);
#endif /* _ESIF_LF_ACTION_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,156 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_lf_action.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified against Windows SDK/DDK included headers which we
* have no control over.
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
/* Debug Logging Defintions */
#define INIT_DEBUG 0
#define GET_DEBUG 1
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_CONST, \
INIT_DEBUG, \
format, \
##__VA_ARGS__)
#define ESIF_TRACE_DYN_GET(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_CONST, \
GET_DEBUG, \
format, \
##__VA_ARGS__)
enum esif_rc esif_get_action_const(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr
)
{
enum esif_rc rc = ESIF_OK;
u32 val;
UNREFERENCED_PARAMETER(lp_ptr);
UNREFERENCED_PARAMETER(primitive_ptr);
UNREFERENCED_PARAMETER(req_data_ptr);
if ((NULL == action_ptr) || (NULL == rsp_data_ptr)) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
val = action_ptr->get_p1_u32(action_ptr);
ESIF_TRACE_DYN_GET("type = %s, value = %d\n",
esif_data_type_str(rsp_data_ptr->type), val);
/*
* Const items are kept as 32-bit values; however, the call may be for
* a different size depending on type. Return data as the largest
* type the buffer passed in can accept.
*/
if (rsp_data_ptr->buf_len >= sizeof(u64)) {
rsp_data_ptr->data_len = sizeof(u64);
*((u64 *)rsp_data_ptr->buf_ptr) = (u64)val;
} else if (rsp_data_ptr->buf_len >= sizeof(u32)) {
rsp_data_ptr->data_len = sizeof(u32);
*((u32 *)rsp_data_ptr->buf_ptr) = (u32)val;
} else if (rsp_data_ptr->buf_len >= sizeof(u16)) {
rsp_data_ptr->data_len = sizeof(u16);
*((u16 *)rsp_data_ptr->buf_ptr) = (u16)val;
} else if (rsp_data_ptr->buf_len >= sizeof(u8)) {
rsp_data_ptr->data_len = sizeof(u8);
*((u8 *)rsp_data_ptr->buf_ptr) = (u8)val;
} else {
/* Should only happen if buffer len is 0 */
ESIF_TRACE_DYN_GET("Buffer insufficient for result = %d\n",
rsp_data_ptr->buf_len);
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
}
exit:
ESIF_TRACE_DYN_GET("RC: %s(%d)\n", esif_rc_str(rc), rc);
return rc;
}
/* Init */
enum esif_rc esif_action_const_init(void)
{
ESIF_TRACE_DYN_INIT("Initialize CONST Action\n");
return ESIF_OK;
}
/* Exit */
void esif_action_const_exit(void)
{
ESIF_TRACE_DYN_INIT("Exit CONST Action\n");
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,239 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_lf_action.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified against Windows SDK/DDK included headers which we
* have no control over.
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
/* Debug Logging Defintions */
#define INIT_DEBUG 0
#define GET_DEBUG 1
#define SET_DEBUG 2
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_MBI, \
INIT_DEBUG, \
format, \
##__VA_ARGS__)
#define ESIF_TRACE_DYN_GET(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_MBI, \
GET_DEBUG, \
format, \
##__VA_ARGS__)
#define ESIF_TRACE_DYN_SET(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_MBI, \
SET_DEBUG, \
format, \
##__VA_ARGS__)
/* Lock */
static esif_ccb_lock_t g_esif_action_mbi_lock;
/* Get */
enum esif_rc esif_get_action_mbi(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr
)
{
enum esif_rc rc = ESIF_OK;
int i = 0; /* Loop Counter */
u32 val = 0; /* Temporary MMIO Value MMIO Always 32 Bit */
u32 bit_mask = 0; /* Bit Mask For MMIO Value */
u8 port;
u8 punit;
u8 bit_from;
u8 bit_to;
UNREFERENCED_PARAMETER(lp_ptr);
UNREFERENCED_PARAMETER(primitive_ptr);
UNREFERENCED_PARAMETER(req_data_ptr);
if ((NULL == action_ptr) || (NULL == rsp_data_ptr)) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
port = (u8)action_ptr->get_p1_u32(action_ptr);
punit = (u8)action_ptr->get_p2_u32(action_ptr);
bit_from = (u8)action_ptr->get_p4_u32(action_ptr);
bit_to = (u8)action_ptr->get_p3_u32(action_ptr);
ESIF_TRACE_DYN_GET(
"port 0x%02x punit 0x%02x bit_from %d bit_to %d\n",
port,
punit,
bit_from,
bit_to);
/* Read MBI 32-Bit Always */
rc = esif_ccb_mbi_read(port, punit, &val);
if (ESIF_OK != rc)
goto exit;
/* Mask Bits */
for (bit_mask = 0, i = bit_from; i <= bit_to; i++)
bit_mask |= (1 << i);
val = val & bit_mask;
val = val >> bit_from;
switch (rsp_data_ptr->type) {
case ESIF_DATA_UINT8:
rsp_data_ptr->data_len = sizeof(u8);
if (rsp_data_ptr->buf_len >= sizeof(u8))
*((u8 *)rsp_data_ptr->buf_ptr) = (u8)val;
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_UINT16:
rsp_data_ptr->data_len = sizeof(u16);
if (rsp_data_ptr->buf_len >= sizeof(u16))
*((u16 *)rsp_data_ptr->buf_ptr) = (u16)val;
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_UINT32:
rsp_data_ptr->data_len = sizeof(u32);
if (rsp_data_ptr->buf_len >= sizeof(u32))
*((u32 *)rsp_data_ptr->buf_ptr) = (u32)val;
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
default:
rc = ESIF_E_UNSUPPORTED_RESULT_DATA_TYPE;
break;
}
exit:
ESIF_TRACE_DYN_GET("RC: %s(%d)\n", esif_rc_str(rc), rc);
return rc;
}
/* Set */
enum esif_rc esif_set_action_mbi(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr
)
{
enum esif_rc rc = ESIF_E_NOT_IMPLEMENTED;
u8 port;
u8 punit;
u8 bit_from;
u8 bit_to;
UNREFERENCED_PARAMETER(lp_ptr);
UNREFERENCED_PARAMETER(primitive_ptr);
UNREFERENCED_PARAMETER(req_data_ptr);
if ((NULL == action_ptr) || (NULL == req_data_ptr)) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
port = (u8)action_ptr->get_p1_u32(action_ptr);
punit = (u8)action_ptr->get_p2_u32(action_ptr);
bit_from = (u8)action_ptr->get_p4_u32(action_ptr);
bit_to = (u8)action_ptr->get_p3_u32(action_ptr);
ESIF_TRACE_DYN_SET(
"req type %s, mbi port %02x punit 0x02%x bit_from %d bit_to %d\n",
esif_data_type_str(req_data_ptr->type),
port,
punit,
bit_from,
bit_to);
exit:
ESIF_TRACE_DYN_SET("RC: %s(%d)\n", esif_rc_str(rc), rc);
return rc;
}
/* Init */
enum esif_rc esif_action_mbi_init(void)
{
ESIF_TRACE_DYN_INIT("Initialize MBI Action\n");
esif_ccb_lock_init(&g_esif_action_mbi_lock);
return ESIF_OK;
}
/* Exit */
void esif_action_mbi_exit(void)
{
esif_ccb_lock_uninit(&g_esif_action_mbi_lock);
ESIF_TRACE_DYN_INIT("Exit MBI Action\n");
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,304 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_lf_action.h"
#include "esif_participant.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified against Windows SDK/DDK included headers which we
* have no control over.
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
/* Debug Logging Defintions */
#define INIT_DEBUG 0
#define GET_DEBUG 1
#define SET_DEBUG 2
#define MMIO_ACCESS_SIZE 4
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_MMIO, \
INIT_DEBUG, \
format, \
##__VA_ARGS__)
#define ESIF_TRACE_DYN_GET(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_MMIO, \
GET_DEBUG, \
format, \
##__VA_ARGS__)
#define ESIF_TRACE_DYN_SET(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_MMIO, \
SET_DEBUG, \
format, \
##__VA_ARGS__)
/* Lock */
static esif_ccb_lock_t g_esif_action_mmio_lock;
/* Get */
enum esif_rc esif_get_action_mmio(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr
)
{
enum esif_rc rc = ESIF_OK;
void __iomem *base_addr = NULL;
u32 offset;
u8 bit_from;
u8 bit_to;
int i = 0; /* Loop Counter */
u32 val = 0; /* Temporary MMIO Value MMIO Always 32 Bit */
u32 bit_mask = 0; /* Bit Mask For MMIO Value */
UNREFERENCED_PARAMETER(primitive_ptr);
UNREFERENCED_PARAMETER(req_data_ptr);
if ((NULL == lp_ptr) || (NULL == action_ptr) ||
(NULL == rsp_data_ptr)) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
base_addr = lp_ptr->pi_ptr->mem_base;
if (NULL == base_addr) {
rc = ESIF_E_NO_MMIO_SUPPORT;
goto exit;
}
offset = action_ptr->get_p1_u32(action_ptr);
bit_from = (u8)action_ptr->get_p3_u32(action_ptr);
bit_to = (u8)action_ptr->get_p2_u32(action_ptr);
#ifdef ESIF_ATTR_OS_WINDOWS
if ((offset + MMIO_ACCESS_SIZE) > lp_ptr->pi_ptr->mem_size) {
rc = ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS;
goto exit;
}
#endif
/* Read MMIO 32-Bit Always */
esif_ccb_read_lock(&g_esif_action_mmio_lock);
esif_ccb_mmio_read(base_addr, offset, &val);
esif_ccb_read_unlock(&g_esif_action_mmio_lock);
/* Mask Bits */
for (bit_mask = 0, i = bit_from; i <= bit_to; i++)
bit_mask |= (1 << i);
val = val & bit_mask;
val = val >> bit_from;
ESIF_TRACE_DYN_GET("Base %p offset 0x%x[%d:%d] = 0x%x\n",
base_addr, offset, bit_to, bit_from, val);
switch (rsp_data_ptr->type) {
case ESIF_DATA_UINT8:
rsp_data_ptr->data_len = sizeof(u8);
if (rsp_data_ptr->buf_len >= sizeof(u8))
*((u8 *)rsp_data_ptr->buf_ptr) = (u8)val;
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_UINT16:
rsp_data_ptr->data_len = sizeof(u16);
if (rsp_data_ptr->buf_len >= sizeof(u16))
*((u16 *)rsp_data_ptr->buf_ptr) = (u16)val;
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_UINT32:
case ESIF_DATA_TIME:
rsp_data_ptr->data_len = sizeof(u32);
if (rsp_data_ptr->buf_len >= sizeof(u32))
*((u32 *)rsp_data_ptr->buf_ptr) = (u32)val;
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
default:
rc = ESIF_E_UNSUPPORTED_RESULT_DATA_TYPE;
break;
}
exit:
ESIF_TRACE_DYN_GET("RC: %s(%d)\n", esif_rc_str(rc), rc);
return rc;
}
/* Set */
enum esif_rc esif_set_action_mmio(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr
)
{
enum esif_rc rc = ESIF_OK;
void __iomem *base_addr = NULL;
u32 offset;
u8 bit_from;
u8 bit_to;
int i = 0; /* Loop Counter */
u32 req_val = 0; /* Request MMIO Value */
u32 orig_val = 0; /* Original Value Of MMIO */
u32 bit_mask = 0; /* Bit Mask */
UNREFERENCED_PARAMETER(primitive_ptr);
if ((NULL == lp_ptr) || (NULL == action_ptr) ||
(NULL == req_data_ptr)) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
base_addr = lp_ptr->pi_ptr->mem_base;
if (NULL == base_addr) {
rc = ESIF_E_NO_MMIO_SUPPORT;
goto exit;
}
offset = action_ptr->get_p1_u32(action_ptr);
bit_from = (u8)action_ptr->get_p3_u32(action_ptr);
bit_to = (u8)action_ptr->get_p2_u32(action_ptr);
#ifdef ESIF_ATTR_OS_WINDOWS
if ((offset + MMIO_ACCESS_SIZE) > lp_ptr->pi_ptr->mem_size) {
rc = ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS;
goto exit;
}
#endif
switch (req_data_ptr->type) {
case ESIF_DATA_UINT8:
if (req_data_ptr->buf_len >= sizeof(u8))
req_val = *((u8 *)req_data_ptr->buf_ptr);
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_UINT16:
if (req_data_ptr->buf_len >= sizeof(u16))
req_val = *((u16 *)req_data_ptr->buf_ptr);
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_UINT32:
case ESIF_DATA_TIME:
if (req_data_ptr->buf_len >= sizeof(u32))
req_val = *((u32 *)req_data_ptr->buf_ptr);
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
default:
rc = ESIF_E_UNSUPPORTED_REQUEST_DATA_TYPE;
break;
}
ESIF_TRACE_DYN_SET("Base %p offset 0x%x[%d:%d] = 0x%x\n",
base_addr, offset, bit_to, bit_from, req_val);
/* Read The Current Value Of The MMIO */
esif_ccb_write_lock(&g_esif_action_mmio_lock);
esif_ccb_mmio_read(base_addr, offset, &orig_val);
/* Mask Bits */
for (bit_mask = 0UL, i = bit_from; i <= bit_to; i++)
bit_mask |= (1UL << i);
/* Shift Bits */
orig_val &= ~(bit_mask);
/* Get the New Value */
req_val = ((req_val << bit_from) & bit_mask) | orig_val;
/* Write MMIO 32-Bit Always */
esif_ccb_mmio_write(base_addr, offset, req_val);
esif_ccb_write_unlock(&g_esif_action_mmio_lock);
exit:
ESIF_TRACE_DYN_SET("RC: %s(%d)\n", esif_rc_str(rc), rc);
return rc;
}
/* Init */
enum esif_rc esif_action_mmio_init(void)
{
ESIF_TRACE_DYN_INIT("Initialize MMIO Action\n");
esif_ccb_lock_init(&g_esif_action_mmio_lock);
return ESIF_OK;
}
/* Exit */
void esif_action_mmio_exit(void)
{
esif_ccb_lock_uninit(&g_esif_action_mmio_lock);
ESIF_TRACE_DYN_INIT("Exit MMIO Action\n");
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,776 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_lf_action.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified against Windows SDK/DDK included headers which we
* have no control over.
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
/* Debug Logging Defintions */
#define INIT_DEBUG 0
#define GET_DEBUG 1
#define SET_DEBUG 2
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_MSR, \
INIT_DEBUG, \
format, \
##__VA_ARGS__)
#define ESIF_TRACE_DYN_GET(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_MSR, \
GET_DEBUG, \
format, \
##__VA_ARGS__)
#define ESIF_TRACE_DYN_SET(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_MSR, \
SET_DEBUG, \
format, \
##__VA_ARGS__)
/* Lock */
static esif_ccb_lock_t g_esif_action_msr_lock;
/* Binary Object - Use the Same Logic As ACPI */
union esif_binary_object {
u8 *buf_ptr;
union esif_data_variant *variant_ptr;
};
enum esif_rc read_mod_write_msr_bit_range(
const u32 msr,
const u8 bit_from,
const u8 bit_to,
u64 val0
);
/* Compare */
static u8 msr_has_same_val(
const u32 msr,
const u64 bit_mask
)
{
u32 cpu = 0;
u32 rc = 0;
u32 once = TRUE;
u64 curr_val = ~(0UL);
u64 first_val = ~(0UL);
u64 cpu_mask = 0;
cpu_mask = esif_ccb_get_online_cpu();
/* Compare If All Active CPUs Have A Same value */
for (cpu = 0; cpu < sizeof(cpu) * 8; cpu++)
if ((cpu_mask & (((u64)0x1UL) << cpu))) {
rc = esif_ccb_read_msr((u8)cpu, msr, &curr_val);
if (ESIF_OK != rc)
return FALSE;
curr_val = curr_val & bit_mask;
if (once) {
first_val = curr_val;
once = FALSE;
} else if (first_val != curr_val) {
return FALSE;
}
}
/* Ok To Be True Even No cpu_mask. MSR Read Func Will Handle Error */
return TRUE;
}
static enum esif_rc read_msr_by_hint(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const enum esif_data_type data_type,
const u32 msr,
const u8 bit_from,
const u8 bit_to,
const u32 hint,
u64 *val
)
{
enum esif_rc rc = ESIF_OK;
u64 curr_val = 0;
u64 curr_msr = 0;
u64 min_val = ~(0UL);
u64 min_msr = ~(0UL);
u64 max_val = 0;
u64 max_msr = 0;
u64 cpu_mask;
u64 bit_mask;
u32 cpu;
u32 i;
if (ESIF_ACTION_MSR_HINT_MAX != hint && ESIF_ACTION_MSR_HINT_MIN != hint)
return ESIF_E_NOT_IMPLEMENTED;
for (bit_mask = 0ULL, i = bit_from; i <= bit_to; i++)
bit_mask |= (1ULL << i);
cpu_mask = esif_ccb_get_online_cpu();
for (cpu = 0; cpu < sizeof(cpu) * 8; cpu++) {
/* Active CPUs */
if ((cpu_mask & (((u64) 0x1UL) << cpu))) {
rc = esif_ccb_read_msr((u8)cpu, msr, &curr_msr);
if (ESIF_OK != rc)
return ESIF_E_MSR_IO_FAILURE;
/* Mask-n-Shift MSR value */
curr_msr = curr_msr & bit_mask;
curr_msr = curr_msr >> bit_from;
/* Max MSR Doesn't Necessary Mean Max Temp/Power */
switch (data_type) {
case ESIF_DATA_TEMPERATURE:
case ESIF_DATA_POWER:
curr_val = curr_msr;
rc = esif_execute_xform_func(lp_ptr,
primitive_ptr,
ESIF_ACTION_MSR,
data_type,
&curr_val);
if (rc != ESIF_OK)
goto exit;
/* Keep Max Value Of Temp/Power and Its MSR */
if (curr_val >= max_val) {
max_val = curr_val;
max_msr = curr_msr;
}
if (curr_val <= min_val) {
min_val = curr_val;
min_msr = curr_msr;
}
break;
default:
max_msr = (curr_msr > max_msr) ? curr_msr :
max_msr;
min_msr = (curr_msr < min_msr) ? curr_msr :
min_msr;
}
ESIF_TRACE_DYN_GET(
"CPU-%d type %s msr 0x%x = {curr 0x%llx "
"max 0x%llx min 0x%llx} "
"val = {curr %llu max %llu min %llu}\n",
cpu, esif_data_type_str(data_type), msr,
curr_msr, max_msr, min_msr,
curr_val, max_val, min_val);
}
}
if (ESIF_ACTION_MSR_HINT_MAX == hint)
*val = max_msr;
else
*val = min_msr;
exit:
return rc;
}
/* Get */
enum esif_rc esif_get_action_msr(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
const struct esif_data *req_data_ptr,
const enum esif_data_type xform_type,
struct esif_data *rsp_data_ptr
)
{
enum esif_rc rc = ESIF_OK;
union esif_binary_object bin;
u32 msr;
u8 bit_from;
u8 bit_to;
u32 hint;
u32 cpus = 0; /* Default CPU */
u64 val = 0;
u64 bit_mask = 0;
u64 cpu_mask = 0;
u32 i;
u32 cpu;
u32 has_ok = 0;
u32 has_failed = 0;
u32 needed_len = 0;
u8 cpu_str[8];
if ((NULL == lp_ptr) || (NULL == primitive_ptr) ||
(NULL == action_ptr) || (NULL == req_data_ptr) ||
(NULL == rsp_data_ptr)) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
msr = action_ptr->get_p1_u32(action_ptr);
bit_from = (u8)action_ptr->get_p3_u32(action_ptr);
bit_to = (u8)action_ptr->get_p2_u32(action_ptr);
/*
* getp_pX_u32() = -1 means the parameter isn't set, 0 is a valid value.
* When p4 (hint) is set, CPU affinity mask is required, either provided by UF
* or use all active CPUs.
*/
hint = action_ptr->get_p4_u32(action_ptr);
if ((int)hint > 0) {
/* Use cpu_affinity_mask from by UF, or all */
if (req_data_ptr->buf_len ==
sizeof(u32) &&
req_data_ptr->type == ESIF_DATA_UINT32) {
cpus = (*(u32 *)req_data_ptr->buf_ptr);
} else {
/* For hint without binary type */
if (rsp_data_ptr->type == ESIF_DATA_UINT8 ||
rsp_data_ptr->type == ESIF_DATA_UINT16 ||
rsp_data_ptr->type == ESIF_DATA_UINT32 ||
rsp_data_ptr->type == ESIF_DATA_UINT64) {
cpus = (u32)(0UL); /* Use 0 */
} else {
cpus = (u32) ~(0UL); /* All */
}
}
}
ESIF_TRACE_DYN_GET(
"Read msr %d[%d:%d] - cpus 0x%x hint %x "
"req_type %s len %d rsp_type %s len %d\n",
msr,
bit_to,
bit_from,
cpus,
hint,
esif_data_type_str(req_data_ptr->type),
req_data_ptr->buf_len,
esif_data_type_str(rsp_data_ptr->type),
rsp_data_ptr->buf_len);
bin.buf_ptr = (u8 *)rsp_data_ptr->buf_ptr;
/*
* cpus = 0, use single CPU (cpu-0)
* cpus > 0, use UF-provided affinity mask (ex, 5 = CPU-0 and CPU-2)
* cpus < 0, unspecified, use all active CPUs
*/
if (cpus == 0) {
/* Mask bits */
for (bit_mask = 0ULL, i = bit_from; i <= bit_to; i++)
bit_mask |= (1ULL << i);
switch (hint) {
case ESIF_ACTION_MSR_HINT_MAX:
case ESIF_ACTION_MSR_HINT_MIN:
rc = read_msr_by_hint(lp_ptr,
primitive_ptr,
xform_type,
msr,
bit_from,
bit_to,
hint,
&val);
if (ESIF_OK != rc)
return rc;
break;
/* Same MSR value across CPUs */
case ESIF_ACTION_MSR_HINT_UNI:
if (!msr_has_same_val(msr, bit_mask))
return ESIF_E_MSR_MULTI_VALUES;
/* BREAK INTENTIONALLY LEFT OUT */
/* No Hint (-1), so use CPU0 */
default:
rc = esif_ccb_read_msr(0, msr, &val);
if (ESIF_OK != rc)
return ESIF_E_MSR_IO_FAILURE;
val = val & bit_mask;
val = val >> bit_from;
}
switch (rsp_data_ptr->type) {
/*
* Expect UF placed a generic reponse type for all similar
* ones, sych as TIME, BIT -> U32, so there is no need to
* list them all here.
*/
case ESIF_DATA_UINT8:
rsp_data_ptr->data_len = sizeof(u8);
if (rsp_data_ptr->buf_len >= sizeof(u8))
*((u8 *)rsp_data_ptr->buf_ptr) = (u8)val;
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_UINT16:
rsp_data_ptr->data_len = sizeof(u16);
if (rsp_data_ptr->buf_len >= sizeof(u16))
*((u16 *)rsp_data_ptr->buf_ptr) = (u16)val;
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_UINT32:
case ESIF_DATA_TIME:
rsp_data_ptr->data_len = sizeof(u32);
if (rsp_data_ptr->buf_len >= sizeof(u32))
*((u32 *)rsp_data_ptr->buf_ptr) = (u32)val;
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_UINT64:
case ESIF_DATA_FREQUENCY:
rsp_data_ptr->data_len = sizeof(u64);
if (rsp_data_ptr->buf_len >= sizeof(u64))
*((u64 *)rsp_data_ptr->buf_ptr) = (u64)val;
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_BINARY:
needed_len += sizeof(union esif_data_variant);
if (needed_len <= rsp_data_ptr->buf_len) {
bin.variant_ptr->integer.type =
ESIF_DATA_UINT64;
bin.variant_ptr->integer.value = (u64)val;
bin.buf_ptr = bin.buf_ptr +
sizeof(union esif_data_variant);
} else {
rc = ESIF_E_NEED_LARGER_BUFFER;
}
/* Update Respond Data Len */
rsp_data_ptr->data_len = needed_len;
break;
default:
rc = ESIF_E_UNSUPPORTED_RESULT_DATA_TYPE;
break;
}
ESIF_TRACE_DYN_GET(
"Single read msr 0x%x[%d:%d] "
"len %d rc %d val 0x%llx\n",
msr,
bit_to,
bit_from,
needed_len,
rc,
val);
} else {
/* The Only Accepted Rsp Data Type For Multi-Thread MSR Read Is
*BINARY */
if (rsp_data_ptr->type != ESIF_DATA_BINARY)
return ESIF_E_NEED_BINARY_BUFFER;
if ((int)cpus > 0)
cpu_mask = cpus;
else
cpu_mask = esif_ccb_get_online_cpu();
/* Multi-Thread Affinity Read */
for (cpu = 0; cpu < sizeof(cpus) * 8; cpu++)
if ((cpu_mask & (((u64)0x1UL) << cpu))) {
/* On CPU i, Read The Current MSR Value */
rc = esif_ccb_read_msr((u8)cpu, msr, &val);
if (ESIF_OK == rc) {
for (bit_mask = 0ULL, i = bit_from; i <= bit_to; i++)
bit_mask |= (1ULL << i);
val = val & bit_mask;
val = val >> bit_from;
/* Need Two Variant Data, One For CPU
* Name, The Other For Value. */
needed_len +=
(sizeof(union esif_data_variant) * 2) +
sizeof(cpu_str);
if (needed_len <= rsp_data_ptr->buf_len) {
/* Format: {{U64, cpu-number},
*{U64, msr-val}} */
bin.variant_ptr->integer.type = ESIF_DATA_UINT64;
bin.variant_ptr->integer.value = (u64)cpu;
bin.buf_ptr = bin.buf_ptr + sizeof(union esif_data_variant);
bin.variant_ptr->integer.type = ESIF_DATA_UINT64;
bin.variant_ptr->integer.value = (u64)val;
bin.buf_ptr = bin.buf_ptr + sizeof(union esif_data_variant);
}
has_ok++;
} else {
has_failed++;
}
}
/* Update Respond Data Len */
rsp_data_ptr->data_len = needed_len;
/*
* Return OK only if all threads read are OK.
* IO_FAILURE if thread can read; otherwise, MSR_AFFINITY if
* some threads can do affinity read.
*/
/*
* TODO: Lifu - ESIF_I_MSR_AFFINITY will make esif_uf
* NOT to show any data
*/
if (needed_len <= rsp_data_ptr->buf_len)
rc = (has_ok) ? ((has_failed == 0) ? ESIF_OK : ESIF_OK)
: ESIF_E_MSR_IO_FAILURE;
else
rc = ESIF_E_NEED_LARGER_BUFFER;
ESIF_TRACE_DYN_GET(
"Multi read msr 0x%x[%d:%d] "
"len %d rc %d passed %d failed %d\n",
msr,
bit_to,
bit_from,
needed_len,
rc,
has_ok,
has_failed);
}
exit:
ESIF_TRACE_DYN_GET("RC: %s(%d)\n", esif_rc_str(rc), rc);
return rc;
}
/* Set */
enum esif_rc esif_set_action_msr(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr
)
{
enum esif_rc rc = ESIF_OK;
u32 msr;
u8 bit_from;
u8 bit_to;
u32 hint;
u32 cpus = 0; /* Default CPU */
u64 saved_val = 0;
u64 val = 0;
u64 orig_val = 0;
u64 bit_mask = 0;
u64 cpu_mask = 0;
u32 i;
u32 has_ok = 0;
u32 has_failed = 0;
UNREFERENCED_PARAMETER(lp_ptr);
UNREFERENCED_PARAMETER(primitive_ptr);
if ((NULL == action_ptr) || (NULL == req_data_ptr)) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
msr = action_ptr->get_p1_u32(action_ptr);
bit_from = (u8)action_ptr->get_p3_u32(action_ptr);
bit_to = (u8)action_ptr->get_p2_u32(action_ptr);
/*
* getp_pX_u32() = -1 means the parameter isn't set, 0 is a valid value.
* When p4 (hint) is set, CPU affinity mask is required, either provided by UF
* or use all active CPUs.
*/
hint = action_ptr->get_p4_u32(action_ptr);
if ((hint > 0)) {
/*
* Expected Request Data {msr_value} or
* {msr_value, cpu_affinity_mask}
*/
if ((req_data_ptr->buf_len == (sizeof(u32) * 2)) &&
(req_data_ptr->type == ESIF_DATA_UINT32)) {
cpus = (*(u32 *)((u8 *)req_data_ptr->buf_ptr + 4));
} else {
cpus = (u32) ~(0UL);
}
}
ESIF_TRACE_DYN_SET(
"Write msr %x[%d:%d] cpu_mask 0x%x "
"hint %x req_type %s len %d\n",
msr,
bit_to,
bit_from,
cpus,
hint,
esif_data_type_str(req_data_ptr->type),
req_data_ptr->buf_len);
switch (req_data_ptr->type) {
case ESIF_DATA_UINT8:
if (req_data_ptr->buf_len >= sizeof(u8))
val = *((u8 *)req_data_ptr->buf_ptr);
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_UINT16:
if (req_data_ptr->buf_len >= sizeof(u16))
val = *((u16 *)req_data_ptr->buf_ptr);
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_UINT32:
case ESIF_DATA_TIME:
if (req_data_ptr->buf_len >= sizeof(u32))
val = *((u32 *)req_data_ptr->buf_ptr);
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_UINT64:
case ESIF_DATA_FREQUENCY:
if (req_data_ptr->buf_len >= sizeof(u64))
val = *((u64 *)req_data_ptr->buf_ptr);
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
/*
* OK to have binary data - only for one item with u64 type.
* We don't yet support multiple data entries for different CPU threads.
*/
case ESIF_DATA_BINARY:
if (req_data_ptr->buf_len >= sizeof(u64))
val = *((u64 *)req_data_ptr->buf_ptr);
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
default:
rc = ESIF_E_UNSUPPORTED_REQUEST_DATA_TYPE;
break;
}
if (ESIF_OK != rc)
return rc;
/* Mask Bits */
for (bit_mask = 0ULL, i = bit_from; i <= bit_to; i++)
bit_mask |= (1ULL << i);
/*
* cpus = 0, Single CPU (CPU-0)
* cpus = 7, Multiple CPUs (CPU-0, 1 and 2)
* cpus = -1, Multiple CPUs (Use all active ones)
*/
if (cpus == 0) {
/* Use CPU0 By Default To Read 64-Bit Current MSR Value */
esif_ccb_write_lock(&g_esif_action_msr_lock);
rc = esif_ccb_read_msr((u8)0, msr, &orig_val);
if (ESIF_OK == rc) {
/* Shift Bits, OR Other Original Bits */
orig_val &= ~(bit_mask);
val = ((val << bit_from) & bit_mask) | orig_val;
/* Write MSR 64-Bit Always */
rc = esif_ccb_write_msr((u8)0, msr, val);
if (ESIF_OK != rc)
rc = ESIF_E_MSR_IO_FAILURE;
} else {
rc = ESIF_E_MSR_IO_FAILURE;
}
esif_ccb_write_unlock(&g_esif_action_msr_lock);
ESIF_TRACE_DYN_GET(
"Single write msr 0x%x[%d:%d] "
"val 0x%llu rc %d\n",
msr,
bit_to,
bit_from,
val,
rc);
} else {
if ((int)cpus > 0)
cpu_mask = cpus;
else
cpu_mask = esif_ccb_get_online_cpu();
/* Multi-Thread Affinity Write */
for (i = 0, saved_val = val; i < sizeof(cpus) * 8; i++)
if ((cpu_mask & (((u64)0x1UL) << i))) {
/* On CPU i, Read Current 64-Bit MSR Value */
rc = esif_ccb_read_msr((u8)i, msr, &orig_val);
if (ESIF_OK == rc) {
/* Shift Bits, OR Other Original Bits */
/* Re-store Original Value */
val = saved_val;
orig_val &= ~(bit_mask);
val = ((val << bit_from) & bit_mask) | orig_val;
/* Write MSR 64-Bit Always */
rc = esif_ccb_write_msr((u8)i,
msr,
val);
if (ESIF_OK == rc)
has_ok++;
else
has_failed++;
} else {
has_failed++;
}
}
/*
* Return OK only if all threads read are OK.
* IO_FAILURE if thread can read; otherwise, MSR_AFFINITY if
* some threads can do affinity read.
*/
rc = (has_ok) ? ((has_failed == 0) ? ESIF_OK : ESIF_OK)
: ESIF_E_MSR_IO_FAILURE;
ESIF_TRACE_DYN_SET(
"Multi write msr 0x%x[%d:%d] "
"val 0x%llu rc %d pass %d fail %d\n",
msr,
bit_to,
bit_from,
val,
rc,
has_ok,
has_failed);
}
exit:
ESIF_TRACE_DYN_SET("RC: %s(%d)\n", esif_rc_str(rc), rc);
return rc;
}
/* Init */
enum esif_rc esif_action_msr_init(void)
{
ESIF_TRACE_DYN_INIT("Initialize MSR Action\n");
esif_ccb_lock_init(&g_esif_action_msr_lock);
return ESIF_OK;
}
/* Exit */
void esif_action_msr_exit(void)
{
esif_ccb_lock_uninit(&g_esif_action_msr_lock);
ESIF_TRACE_DYN_INIT("Exit MSR Action\n");
}
enum esif_rc read_mod_write_msr_bit_range(
const u32 msr,
const u8 bit_from,
const u8 bit_to,
u64 val
)
{
enum esif_rc rc = ESIF_OK;
u64 bit_mask = 0;
u64 orig_val = 0;
u32 i;
esif_ccb_write_lock(&g_esif_action_msr_lock);
/* Mask Bits */
for (bit_mask = 0ULL, i = bit_from; i <= bit_to; i++)
bit_mask |= (1ULL << i);
/* Use CPU0 By Default To Read 64-Bit Current MSR Value */
rc = esif_ccb_read_msr((u8)0, msr, &orig_val);
if (ESIF_OK != rc) {
rc = ESIF_E_MSR_IO_FAILURE;
goto exit;
}
/* Shift Bits, OR Other Original Bits */
orig_val &= ~(bit_mask);
val = ((val << bit_from) & bit_mask) | orig_val;
/* Write MSR 64-Bit Always */
rc = esif_ccb_write_msr((u8)0, msr, val);
if (ESIF_OK != rc)
rc = ESIF_E_MSR_IO_FAILURE;
exit:
esif_ccb_write_unlock(&g_esif_action_msr_lock);
ESIF_TRACE_DYN_GET(
"Single write msr 0x%x[%d:%d] "
"val 0x%llu rc %s\n",
msr, bit_to, bit_from, val, esif_rc_str(rc));
return rc;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,187 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_lf_action.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified against Windows SDK/DDK included headers which
* we have no control over.
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
/* Debug Logging Defintions */
#define INIT_DEBUG 0
#define GET_DEBUG 1
#define SET_DEBUG 1
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_SYSTEMIO, \
INIT_DEBUG, \
format, \
##__VA_ARGS__)
#define ESIF_TRACE_DYN_GET(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_SYSTEMIO, \
GET_DEBUG, \
format, \
##__VA_ARGS__)
#define ESIF_TRACE_DYN_SET(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_SYSTEMIO, \
GET_DEBUG, \
format, \
##__VA_ARGS__)
/* Lock */
static esif_ccb_lock_t g_esif_action_systemio_lock;
enum esif_rc esif_get_action_systemio(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr
)
{
enum esif_rc rc = ESIF_OK;
u32 val = 1234;
UNREFERENCED_PARAMETER(lp_ptr);
UNREFERENCED_PARAMETER(primitive_ptr);
UNREFERENCED_PARAMETER(action_ptr);
UNREFERENCED_PARAMETER(req_data_ptr);
if (NULL == rsp_data_ptr) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
ESIF_TRACE_DYN_GET("val = %d\n", val);
switch (rsp_data_ptr->type) {
case ESIF_DATA_UINT8:
rsp_data_ptr->data_len = sizeof(u8);
if (rsp_data_ptr->buf_len >= sizeof(u8))
*((u8 *)rsp_data_ptr->buf_ptr) = (u8)val;
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_UINT16:
rsp_data_ptr->data_len = sizeof(u16);
if (rsp_data_ptr->buf_len >= sizeof(u16))
*((u16 *)rsp_data_ptr->buf_ptr) = (u16)val;
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
case ESIF_DATA_UINT32:
rsp_data_ptr->data_len = sizeof(u32);
if (rsp_data_ptr->buf_len >= sizeof(u32))
*((u32 *)rsp_data_ptr->buf_ptr) = (u32)val;
else
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
break;
default:
ESIF_TRACE_DYN_GET("Data Type Not Implemented = %s\n",
esif_data_type_str(rsp_data_ptr->type));
rc = ESIF_E_NOT_IMPLEMENTED;
break;
}
exit:
ESIF_TRACE_DYN_GET("RC: %s(%d)\n", esif_rc_str(rc), rc);
return rc;
}
enum esif_rc esif_set_action_systemio(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr
)
{
UNREFERENCED_PARAMETER(lp_ptr);
UNREFERENCED_PARAMETER(primitive_ptr);
UNREFERENCED_PARAMETER(action_ptr);
UNREFERENCED_PARAMETER(req_data_ptr);
return ESIF_E_NOT_IMPLEMENTED;
}
/* Init */
enum esif_rc esif_action_systemio_init(void)
{
ESIF_TRACE_DYN_INIT("Initialize SYSTEMIO Action\n");
esif_ccb_lock_init(&g_esif_action_systemio_lock);
return ESIF_OK;
}
/* Exit */
void esif_action_systemio_exit(void)
{
ESIF_TRACE_DYN_INIT("Exit SYSTEMIO Action\n");
esif_ccb_lock_uninit(&g_esif_action_systemio_lock);
}
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,232 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_lf_action.h"
#include "esif_primitive.h"
#include "esif_participant.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified against Windows SDK/DDK included headers which we
* have no control over.
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
/* Debug Logging Defintions */
#define INIT_DEBUG 0
#define GET_DEBUG 1
#define SET_DEBUG 2
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_VAR, \
INIT_DEBUG, \
format, \
##__VA_ARGS__)
#define ESIF_TRACE_DYN_GET(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_VAR, \
GET_DEBUG, \
format, \
##__VA_ARGS__)
#define ESIF_TRACE_DYN_SET(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_VAR, \
SET_DEBUG, \
format, \
##__VA_ARGS__)
/* Get Action VAR */
enum esif_rc esif_get_action_var(
const struct esif_lp *lp_ptr,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr
)
{
enum esif_rc rc = ESIF_OK;
u32 val;
struct esif_data local = {ESIF_DATA_UINT32, &val, sizeof(val)};
struct esif_data *var_ptr = NULL;
UNREFERENCED_PARAMETER(lp_ptr);
UNREFERENCED_PARAMETER(req_data_ptr);
if ((NULL == primitive_ptr) || (NULL == action_ptr) ||
(NULL == rsp_data_ptr)) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
val = action_ptr->get_p1_u32(action_ptr);
/* Use Context Variable If Available */
if (primitive_ptr->context_ptr != NULL)
var_ptr = primitive_ptr->context_ptr;
else
var_ptr = &local;
if (NULL == var_ptr) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
if (rsp_data_ptr->buf_len < var_ptr->buf_len) {
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
goto exit;
}
rsp_data_ptr->type = var_ptr->type;
rsp_data_ptr->data_len = var_ptr->buf_len;
esif_ccb_memcpy(rsp_data_ptr->buf_ptr,
var_ptr->buf_ptr,
var_ptr->buf_len);
ESIF_TRACE_DYN_GET("Value 0x%x, buf_type - %s, data_len - %d\n",
val, esif_data_type_str(rsp_data_ptr->type),
rsp_data_ptr->data_len);
exit:
ESIF_TRACE_DYN_GET("RC: %s(%d)\n", esif_rc_str(rc), rc);
return rc;
}
/* Set Action VAR */
enum esif_rc esif_set_action_var(
const struct esif_lp *lp_ptr,
struct esif_lp_primitive *primitive_ptr,
const struct esif_lp_action *action_ptr,
struct esif_data *req_data_ptr
)
{
enum esif_rc rc = ESIF_OK;
struct esif_data *var_ptr = NULL;
struct esif_primitive_tuple tup;
struct esif_lp_primitive *p = NULL;
if ((NULL == lp_ptr) || (NULL == primitive_ptr) ||
(NULL == action_ptr) || (NULL == req_data_ptr) ||
(NULL == lp_ptr->dsp_ptr)) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
/* Create a State Variable To Hold Our Context */
if (NULL == primitive_ptr->context_ptr) {
primitive_ptr->context_ptr = esif_data_alloc(req_data_ptr->type,
req_data_ptr->buf_len);
}
var_ptr = primitive_ptr->context_ptr;
if (NULL == var_ptr) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
if (req_data_ptr->buf_len > var_ptr->buf_len) {
rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
goto exit;
}
var_ptr->type = req_data_ptr->type;
var_ptr->buf_len = req_data_ptr->buf_len;
esif_ccb_memcpy(var_ptr->buf_ptr,
req_data_ptr->buf_ptr,
req_data_ptr->buf_len);
ESIF_TRACE_DYN_SET("buf_type - %s, data_len - %d\n",
esif_data_type_str(req_data_ptr->type),
req_data_ptr->data_len);
/* Find Get To Go With This Set Relationship */
tup.id = (u16)action_ptr->get_p1_u32( action_ptr);
tup.domain = (u16)action_ptr->get_p2_u32( action_ptr);
tup.instance = (u8)action_ptr->get_p3_u32( action_ptr);
ESIF_TRACE_DYN_SET("Find Get For Set, data %d.%d.%d\n",
tup.id,
tup.domain,
tup.instance);
p = lp_ptr->dsp_ptr->get_primitive(lp_ptr->dsp_ptr, &tup);
p->context_ptr = primitive_ptr->context_ptr;
exit:
ESIF_TRACE_DYN_SET("RC: %s(%d)\n", esif_rc_str(rc), rc);
return rc;
}
/* Init */
enum esif_rc esif_action_var_init(void)
{
ESIF_TRACE_DYN_INIT("Initialize VAR Action\n");
return ESIF_OK;
}
/* Exit */
void esif_action_var_exit(void)
{
ESIF_TRACE_DYN_INIT("Exit VAR Action\n");
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,166 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_CAMARILLO_REGS_H_
#define _ESIF_CAMARILLO_REGS_H_
/*
* /////////////////////////////////////////////////////////////////////////////
* General Definitions
* /////////////////////////////////////////////////////////////////////////////
*/
#define OFFSET_PKG_THERM_CAMARILLO_INTERRUPT_HSW 0x5820
#define OFFSET_DDR_THERM_CAMARILLO_INTERRUPT_HSW 0x58A0
#define OFFSET_PKG_THERM_CAMARILLO_STATUS_HSW 0x6200
#define OFFSET_DDR_THERM_CAMARILLO_STATUS_HSW 0x6204
#define PCI_CAMARILLO_INTSTAT 0xDC
#define CAMARILLO_INTSTAT_MASK 0x01
/*
* /////////////////////////////////////////////////////////////////////////////
* Type Declarations
* /////////////////////////////////////////////////////////////////////////////
*/
union reg_pkg_therm_camarillo_interrupt_hsw {
/* OFFSET_PKG_THERM_CAMARILLO_INTERRUPT_HSW 0x5820 */
struct {
u32 HIGH_TEMP_INT_ENABLE:1; /* 0 - */
u32 LOW_TEMP_INT_ENABLE:1; /* 1 - */
u32 PROCHOT_INT_ENABLE:1; /* 2 - */
u32 Rsvd1:1; /* 3 - */
u32 OUT_OF_SPEC_INT_ENABLE:1; /* 4 - */
u32 Rsvd2:3; /* 7:5 - */
u32 THRESHOLD_1_REL_TEMP:7; /* 14:8 - */
u32 THRESHOLD_1_INT_ENABLE:1; /* 15 - */
u32 THRESHOLD_2_REL_TEMP:7; /* 22:16 - */
u32 THRESHOLD_2_INT_ENABLE:1; /* 23 - */
u32 POWER_INT_ENABLE:1; /* 24 - */
u32 Rsvd3:7; /* 31:25 */
} u;
u32 asDword;
};
union reg_ddr_therm_camarillo_interrupt_hsw {
/* OFFSET_DDR_THERM_CAMARILLO_INTERRUPT_HSW 0x58A0 */
struct {
UINT32 ENABLE_WARM_INTERRUPT:1; /* 0 - */
UINT32 Rsvd1:1; /* 1 */
UINT32 ENABLE_HOT_INTERRUPT:1; /* 2 - */
UINT32 Rsvd2:1; /* 3 */
UINT32 ENABLE_2X_REFRESH_INTERRUPT:1; /* 4 - */
UINT32 Rsvd3:3; /* 7:5 */
UINT32 ENABLE_THRESHOLD1_INTERRUPT:1; /* 8 - */
UINT32 Rsvd4:1; /* 9 */
UINT32 ENABLE_THRESHOLD2_INTERRUPT:1; /* 10 - */
UINT32 Rsvd5:5; /* 15:11 */
UINT32 POLICY_FREE_THRESHOLD1:8; /* 23:16 - */
UINT32 POLICY_FREE_THRESHOLD2:8; /* 31:24 - */
} u;
UINT32 asDword;
};
union reg_pkg_therm_camarillo_status_hsw {
/* OFFSET_PKG_THERM_CAMARILLO_STATUS_HSW 0x6200 */
struct {
UINT32 THERMAL_MONITOR_STATUS:1; /* 0 - */
UINT32 THERMAL_MONITOR_LOG:1; /* 1 - */
UINT32 PROCHOT_STATUS:1; /* 2 - */
UINT32 PROCHOT_LOG:1; /* 3 - */
UINT32 OUT_OF_SPEC_STATUS:1; /* 4 - */
UINT32 OUT_OF_SPEC_LOG:1; /* 5 - */
UINT32 THRESHOLD1_STATUS:1; /* 6 - */
UINT32 THRESHOLD1_LOG:1; /* 7 - */
UINT32 THRESHOLD2_STATUS:1; /* 8 - */
UINT32 THRESHOLD2_LOG:1; /* 9 - */
UINT32 POWER_LIMITATION_STATUS:1; /* 10 - */
UINT32 POWER_LIMITATION_LOG:1; /* 11 - */
UINT32 Rsvd1:4; /* 15:12 */
UINT32 Temperature:7; /* 22:16 */
UINT32 Rsvd2:4; /* 26:23 */
UINT32 Resolution:4; /* 30:27 */
UINT32 Valid:1; /* 31 */
} u;
UINT32 asDword;
};
union reg_ddr_therm_camarillo_status_hsw {
/* OFFSET_DDR_THERM_CAMARILLO_STATUS_HSW 0x6204 */
struct {
UINT32 WARM_THRESHOLD_STATUS:1; /* 0 - */
UINT32 WARM_THRESHOLD_LOG:1; /* 1 - */
UINT32 HOT_THRESHOLD_STATUS:1; /* 2 - */
UINT32 HOT_THRESHOLD_LOG:1; /* 3 - */
UINT32 REFRESH2X_STATUS:1; /* 4 - */
UINT32 REFRESH2X_LOG:1; /* 5 - */
UINT32 FORCEMEMPR_STATUS:1; /* 6 - */
UINT32 FORCEMEMPR_LOG:1; /* 7 - */
UINT32 THRESHOLD1_STATUS:1; /* 8 - */
UINT32 THRESHOLD1_LOG:1; /* 9 - */
UINT32 THRESHOLD2_STATUS:1; /* 10 - */
UINT32 THRESHOLD2_LOG:1; /* 11 - */
UINT32 Rsvd1:20; /* 31:12 */
} u;
UINT32 asDword;
};
#endif /* _ESIF_CAMARILLO_REGS_H_ */

View File

@@ -0,0 +1,763 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_CCB_ACPI_H_
#define _ESIF_CCB_ACPI_H_
#include "esif_data.h" /* ESIF Data Buffer */
#include "esif_debug.h"
#ifdef ESIF_ATTR_OS_LINUX
#define esif_ccb_acpi_get_name acpi_get_name
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
#define ACPI_TYPE_INTEGER ACPI_METHOD_ARGUMENT_INTEGER /* 0 */
#define ACPI_TYPE_STRING ACPI_METHOD_ARGUMENT_STRING /* 1 */
#define ACPI_TYPE_BUFFER ACPI_METHOD_ARGUMENT_BUFFER /* 2 */
#define ACPI_TYPE_PACKAGE ACPI_METHOD_ARGUMENT_PACKAGE /* 3 */
#define ACPI_TYPE_LOCAL_REFERENCE 0xfffffff1 /* Non-existing value */
#define ACPI_TYPE_POWER 0xfffffff2 /* Non-existing value */
#define ACPI_TYPE_PROCESSOR 0xfffffff3 /* Non-existing value */
#define AE_OK 0x0000 /* Follow Linux AE Error Code */
#define AE_ERROR 0x0001
#define AE_NOT_FOUND 0x0005
#define do_div(x, y) x = x / y
#define esif_ccb_acpi_get_name(handle, pathname, ref) \
(ESIF_E_UNSUPPORTED_ACTION_TYPE)
#define ACPI_FULL_PATHNAME
#include <acpiioct.h> /* ACPI */
typedef WDFDEVICE acpi_handle; /* We base ACPI on Intel */
typedef u64 acpi_size; /* ACPI Size */
typedef u32 acpi_status; /* ACPI Status Value */
typedef char *acpi_string; /* ACPI String */
typedef u16 acpi_object_type; /* General Type */
typedef u16 esif_acpi_p_type; /* Package Type and Length */
/* Emulate Intel ACPI-CA acpi_object */
#define ACPI_ALLOCATE_BUFFER (-1)
struct acpi_buffer {
int length; /* Length in bytes of the buffer -1 to allocate memory */
void *pointer; /* pointer to buffer */
};
#pragma pack(push, 1)
union acpi_object {
acpi_object_type type; /* MS ARGUMENT:Type */
struct {
acpi_object_type type; /* MS ARGUMENT:Type */
u16 length; /* MS ARGUMENT:DataLength */
u32 value; /* MS ARGUMENT:UNION.Argument */
} integer;
struct {
acpi_object_type type; /* MS ARGUMENT:Type */
u16 length; /* MS ARGUMENT:DataLength */
u8 *pointer; /* MS ARGUMENT:Data */
} string;
struct {
acpi_object_type type; /* MS ARGUMENT:Type */
u16 length; /* MS ARGUMENT:DataLength */
u8 *pointer; /* MS ARGUMENT:Data */
} buffer;
struct {
acpi_object_type type; /* MS ARGUMENT:Type */
u16 count; /* MS ARGUMENT:DataLength NOT COUNT */
union acpi_object *elements; /* MS ARGUMENT:Data
* */
} package;
struct { /* MS Not Used */
acpi_object_type type;
acpi_object_type actual_type;
acpi_handle handle;
} reference;
struct { /* MS Not Used */
acpi_object_type type;
u32 proc_id;
u64 pblk_address;
u32 pblk_length;
} processor;
struct {/* MS Not Used */
acpi_object_type type;
u32 system_level;
u32 resource_order;
} power_resource;
};
#pragma pack(pop)
struct acpi_object_list {
u32 count;
union acpi_object *pointer;
};
#include "win/esif_lf_os_win.h" /* ACPI Helpers */
#endif
/* ACPI Type String */
static ESIF_INLINE char *esif_acpi_type_str(u32 type)
{
#define CREATE_ACPI_TYPE(t, str) case t: str = #t; break;
char *str = ESIF_NOT_AVAILABLE;
switch (type) {
CREATE_ACPI_TYPE(ACPI_TYPE_INTEGER, str);
CREATE_ACPI_TYPE(ACPI_TYPE_STRING, str);
CREATE_ACPI_TYPE(ACPI_TYPE_BUFFER, str);
CREATE_ACPI_TYPE(ACPI_TYPE_PACKAGE, str);
CREATE_ACPI_TYPE(ACPI_TYPE_POWER, str);
CREATE_ACPI_TYPE(ACPI_TYPE_PROCESSOR, str);
#ifdef ESIF_ATTR_OS_LINUX
CREATE_ACPI_TYPE(ACPI_TYPE_ANY, str);
CREATE_ACPI_TYPE(ACPI_TYPE_FIELD_UNIT, str);
CREATE_ACPI_TYPE(ACPI_TYPE_DEVICE, str);
CREATE_ACPI_TYPE(ACPI_TYPE_EVENT, str);
CREATE_ACPI_TYPE(ACPI_TYPE_METHOD, str);
CREATE_ACPI_TYPE(ACPI_TYPE_MUTEX, str);
CREATE_ACPI_TYPE(ACPI_TYPE_REGION, str);
CREATE_ACPI_TYPE(ACPI_TYPE_THERMAL, str);
CREATE_ACPI_TYPE(ACPI_TYPE_BUFFER_FIELD, str);
CREATE_ACPI_TYPE(ACPI_TYPE_DDB_HANDLE, str);
CREATE_ACPI_TYPE(ACPI_TYPE_DEBUG_OBJECT, str);
#endif
}
return str;
}
static ESIF_INLINE acpi_status esif_ccb_acpi_evaluate_object(
acpi_handle handle,
acpi_string acpi_method,
struct acpi_object_list *in_params_ptr,
struct acpi_buffer *return_buffer_ptr
)
{
acpi_status rc = 0;
int orig_length = 0;
if (NULL != return_buffer_ptr)
orig_length = return_buffer_ptr->length;
rc = acpi_evaluate_object(handle,
acpi_method,
in_params_ptr,
return_buffer_ptr);
if (NULL != return_buffer_ptr && NULL != return_buffer_ptr->pointer &&
ACPI_ALLOCATE_BUFFER == orig_length) {
memstat_inc(&g_memstat.allocs); /* Increment in Linux Only Not *Windows! */
}
#ifdef ESIF_ATTR_OS_LINUX
return rc;
#endif
/* Align Windows NTSTATUS to Linux AE error code */
#ifdef ESIF_ATTR_OS_WINDOWS
if (NT_SUCCESS(rc))
return AE_OK;
switch (rc) {
case STATUS_OBJECT_NAME_NOT_FOUND:
return AE_NOT_FOUND;
/*
* TODO: Need a better error mapping, for now, have all Win ACPI errors
* map to *AE_ERROR
*/
case STATUS_ACPI_INVALID_OPCODE:
case STATUS_ACPI_STACK_OVERFLOW:
case STATUS_ACPI_ASSERT_FAILED:
case STATUS_ACPI_INVALID_INDEX:
case STATUS_ACPI_INVALID_ARGUMENT:
case STATUS_ACPI_FATAL:
case STATUS_ACPI_INVALID_ARGTYPE:
case STATUS_ACPI_INVALID_OBJTYPE:
case STATUS_ACPI_INVALID_TARGETTYPE:
case STATUS_ACPI_INCORRECT_ARGUMENT_COUNT:
case STATUS_ACPI_ADDRESS_NOT_MAPPED:
case STATUS_ACPI_INVALID_EVENTTYPE:
case STATUS_ACPI_HANDLER_COLLISION:
case STATUS_ACPI_INVALID_DATA:
case STATUS_ACPI_INVALID_REGION:
case STATUS_ACPI_INVALID_ACCESS_SIZE:
case STATUS_ACPI_ACQUIRE_GLOBAL_LOCK:
case STATUS_ACPI_ALREADY_INITIALIZED:
case STATUS_ACPI_NOT_INITIALIZED:
case STATUS_ACPI_INVALID_MUTEX_LEVEL:
case STATUS_ACPI_MUTEX_NOT_OWNED:
case STATUS_ACPI_RS_ACCESS:
case STATUS_ACPI_INVALID_TABLE:
case STATUS_ACPI_REG_HANDLER_FAILED:
case STATUS_ACPI_POWER_REQUEST_FAILED:
default:
return AE_ERROR;
}
#endif
}
/* Get Argument Count */
static ESIF_INLINE u32 esif_ccb_acpi_arg_count(struct acpi_buffer *buf_ptr)
{
u32 count = 0;
#ifdef ESIF_ATTR_OS_LINUX
if (NULL == buf_ptr)
return 0;
count = 1;
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
ACPI_EVAL_OUTPUT_BUFFER *aeob_ptr = NULL;
if (NULL == buf_ptr)
return 0;
aeob_ptr = (ACPI_EVAL_OUTPUT_BUFFER *)buf_ptr->pointer;
if (aeob_ptr->Signature == ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE)
count = aeob_ptr->Count;
#endif
return count;
}
/* Get ACPI Object */
static ESIF_INLINE union acpi_object
*esif_ccb_acpi_arg_first(struct acpi_buffer *buf_ptr)
{
#ifdef ESIF_ATTR_OS_LINUX
if (NULL == buf_ptr)
return NULL;
return (union acpi_object *)buf_ptr->pointer;
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
ACPI_EVAL_OUTPUT_BUFFER *aeob_ptr = NULL;
if (NULL == buf_ptr)
return NULL;
aeob_ptr = (ACPI_EVAL_OUTPUT_BUFFER *)buf_ptr->pointer;
if (aeob_ptr->Signature == ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE)
return (union acpi_object *)&aeob_ptr->Argument[0];
return NULL;
#endif
}
static ESIF_INLINE union acpi_object *esif_acpi_arg_next(
union acpi_object *obj_ptr)
{
#ifdef ESIF_ATTR_OS_LINUX
return NULL;
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
PACPI_METHOD_ARGUMENT ama_ptr = NULL;
if (NULL == obj_ptr)
return NULL;
ama_ptr = (ACPI_METHOD_ARGUMENT *)obj_ptr;
ama_ptr = ACPI_METHOD_NEXT_ARGUMENT(ama_ptr);
return (union acpi_object *)ama_ptr;
#endif
}
static ESIF_INLINE enum esif_rc esif_handle_osc_buf(
struct acpi_buffer *output,
struct esif_data *req_data_ptr
)
{
enum esif_rc rc = ESIF_E_ACPI_EVAL_FAILURE;
struct esif_data_complex_osc *osc_ptr =
(struct esif_data_complex_osc *)req_data_ptr->buf_ptr;
acpi_status acpi_stat = 0;
#ifdef ESIF_ATTR_OS_LINUX
union acpi_object *out_obj = NULL;
if ((NULL == output) || (NULL == output->pointer))
goto exit;
out_obj = (union acpi_object *)output->pointer;
if (NULL == out_obj->buffer.pointer)
goto exit;
osc_ptr->status = *((u32 *)out_obj->buffer.pointer);
acpi_stat = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
PACPI_EVAL_OUTPUT_BUFFER aeob_ptr = NULL;
PACPI_METHOD_ARGUMENT method_arg = NULL;
PULONG temp = NULL;
if ((NULL == output) || (NULL == output->pointer))
goto exit;
aeob_ptr = (ACPI_EVAL_OUTPUT_BUFFER *)output->pointer;
method_arg = aeob_ptr->Argument;
if (NULL == method_arg)
goto exit;
temp = (PULONG)method_arg->Data;
if (NULL == temp)
goto exit;
osc_ptr->status = *temp;
acpi_stat = osc_ptr->status;
#endif
if (acpi_stat) {
/*
* OSC_REQUEST_ERROR(1), OSC_INVALID_UUID_ERROR(4),
* OSC_INVALID_REVISION_ERROR(8),
* OSC_CAPABILITIES_MASK_ERROR(16)
*/
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_ACPI,
ESIF_TRACE_CATEGORY_ERROR,
"_OSC set error, acpi_stat 0x%x\n",
acpi_stat);
if (acpi_stat & 0x2) {
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_ACPI,
ESIF_TRACE_CATEGORY_ERROR,
"_OSC error - Platform Support _OSC but "
"unable to process _OSC request\n");
}
if (acpi_stat & 0x4) {
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_ACPI,
ESIF_TRACE_CATEGORY_ERROR,
"_OSC error - Platform failed _OSC reason: "
"Unrecognized UUID\n");
}
if (acpi_stat & 0x8) {
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_ACPI,
ESIF_TRACE_CATEGORY_ERROR,
"_OSC error - Platform failed _OSC reason: "
"Unrecognized revision\n");
}
if (acpi_stat & 0x10) {
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ACTION_ACPI,
ESIF_TRACE_CATEGORY_ERROR,
"_OSC error - Platform failed _OSC reason: "
"Unrecognized capability mask\n");
}
goto exit;
}
rc = ESIF_OK;
exit:
return rc;
}
/*
* _OSC Linux Format (32-bit)
* <0x00> {03 00 00 00, 10 00 00 00, PO IN TE R0} 00 00 00 00 (4b padding)
* <0x10> {01 00 00 00, 01 00 00 00 00 00 00 00} 00 00 00 00 (4b padding)
* <0x20> {01 00 00 00, 01 00 00 00 00 00 00 00} 00 00 00 00 (4b padding)
* <0x30> {01 00 00 00, 08 00 00 00 PO IN TE R0} 00 00 00 00 (4b padding)
*
* TODO: need to confirm!
* _OSC Windows Format: (32-bite)
* <0x00> {03 00, 10 00, 16 BY TE -- GU ID 00 00 00 00 00 00 00 00 00 00}
* <0x18> {01 00, 04 00, 01 00 00 00}
* <0x20> {04 00, 02 00 00 00}
* <0x28> {03 00, 08 00, 00 00 00 00 00 00 00 00}
*
*/
static ESIF_INLINE void esif_create_acpi_buffer(
const u32 acpi_method,
struct acpi_object_list *arg_list,
struct esif_data *req_data_ptr
)
{
union acpi_object *acpi_obj = arg_list->pointer;
switch (acpi_method) {
case 'CSO_':
{
struct esif_data_complex_osc *osc =
(struct esif_data_complex_osc *)req_data_ptr->buf_ptr;
/* First Argument - copy GUID from request buffer */
acpi_obj->buffer.type = ACPI_TYPE_BUFFER;
acpi_obj->buffer.length = 16; /* Sizeof GUID */
#ifdef ESIF_ATTR_OS_LINUX
acpi_obj->buffer.pointer = (u8 *)osc->guid;
acpi_obj =
(union acpi_object *)((u8 *)acpi_obj +
sizeof(union acpi_object));
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
/* On Windows, Use &acpi_obj->buffer.pointer Do NOT use
*esif_acpi_memcpy!!! */
acpi_obj->buffer.pointer =
((u8 *)acpi_obj + (sizeof(acpi_obj->buffer) -
sizeof(acpi_obj->buffer.pointer)));
esif_ccb_memcpy(&acpi_obj->buffer.pointer, &osc->guid, 16);
acpi_obj =
(union acpi_object *)((u8 *)acpi_obj +
sizeof(acpi_obj->buffer) -
sizeof(acpi_obj->buffer.pointer)
+ 16);
#endif
/* Second Argument - copy revision from request buffer */
acpi_obj->integer.type = ACPI_TYPE_INTEGER;
acpi_obj->integer.value = osc->revision;
#ifdef ESIF_ATTR_OS_LINUX
acpi_obj =
(union acpi_object *)((u8 *)acpi_obj +
sizeof(union acpi_object));
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
acpi_obj->integer.length = sizeof(acpi_obj->integer.value);
acpi_obj =
(union acpi_object *)((u8 *)acpi_obj +
sizeof(acpi_obj->integer));
#endif
/* Third Argument - copy count from request buffer */
acpi_obj->integer.type = ACPI_TYPE_INTEGER;
acpi_obj->integer.value = osc->count;
#ifdef ESIF_ATTR_OS_LINUX
acpi_obj =
(union acpi_object *)((u8 *)acpi_obj +
sizeof(union acpi_object));
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
acpi_obj->integer.length = sizeof(acpi_obj->integer.value);
acpi_obj =
(union acpi_object *)((u8 *)acpi_obj +
sizeof(acpi_obj->integer));
#endif
/* Forth Argument - copy capability from request buffer */
acpi_obj->buffer.type = ACPI_TYPE_BUFFER;
acpi_obj->buffer.length = (u16)(osc->count * sizeof(u32));
#ifdef ESIF_ATTR_OS_LINUX
acpi_obj->buffer.pointer = (u8 *)&osc->status;
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
/* On Windows, Use &acpi_obj->buffer.pointer!!! Do NOT use
*esif_acpi_memcpy!!! */
acpi_obj->buffer.pointer =
((u8 *)acpi_obj + (sizeof(acpi_obj->buffer) -
sizeof(acpi_obj->buffer.pointer)));
esif_ccb_memcpy(&acpi_obj->buffer.pointer,
&osc->status,
acpi_obj->buffer.length);
#endif
}
break;
default:
{
u8 *buf_ptr = (u8 *)req_data_ptr->buf_ptr;
u32 i;
/*
* buf_ptr points the requested ESIF data buffer in void*,
* counter tells how many, and in_args is real data
* presentation for underlying ACPI driver
*/
for (i = 0; i < arg_list->count; i++) {
acpi_obj->integer.type = ACPI_TYPE_INTEGER;
#ifdef ESIF_ATTR_OS_WINDOWS
acpi_obj->integer.length = sizeof(acpi_obj->integer.value);
#endif
switch (req_data_ptr->type) {
case ESIF_DATA_UINT8:
acpi_obj->integer.value = *((u8 *)buf_ptr);
buf_ptr += sizeof(u8);
break;
case ESIF_DATA_UINT16:
buf_ptr += sizeof(u16);
break;
case ESIF_DATA_UINT32:
acpi_obj->integer.value = *((u32 *)buf_ptr);
buf_ptr += sizeof(u32);
break;
case ESIF_DATA_UINT64:
case ESIF_DATA_FREQUENCY:
/* For 32-bit Windows, it's type ULONG 4-byte */
acpi_obj->integer.value = *((u32 *)buf_ptr);
buf_ptr += sizeof(u64);
break;
default:
break;
}
/* Note: don't do arg_p++, it doesn't work out as
*expected on Windows */
acpi_obj = (union acpi_object *)
((u8 *)acpi_obj + sizeof(acpi_obj->integer));
}
}
break;
}
return;
}
/*
* ACPI Package Processing
*/
#define ESIF_NO_ACPI_TYPE 0xffff
#define ESIF_TABLE_NO_REVISION 0xffff
/* Context For Binary Data Parse / Recursive */
struct esif_action_data {
struct esif_data *rsp_data_ptr;
u32 needed_len;
u16 revision, rows, cols, need_revision;
u16 first_type, second_type, third_type;
enum esif_rc rc;
};
static ESIF_INLINE void esif_acpi_check_revision(
struct esif_action_data *data_ptr)
{
/*
* Maybe it looks like a very strange logic, but this is all due to Linux and
* Windows have very different data layout and design, particularly in package
* type making it impossible to have one set of abstraction.
*/
#ifdef ESIF_ATTR_OS_WINDOWS
if (data_ptr->first_type == ACPI_TYPE_INTEGER &&
data_ptr->second_type == ACPI_TYPE_PACKAGE) {
data_ptr->rows--;
} else {
data_ptr->revision = ESIF_TABLE_NO_REVISION;
}
#endif
#ifdef ESIF_ATTR_OS_LINUX
if (data_ptr->first_type == ACPI_TYPE_PACKAGE &&
data_ptr->second_type == ACPI_TYPE_INTEGER &&
data_ptr->third_type == ACPI_TYPE_PACKAGE) {
data_ptr->rows--;
} else {
data_ptr->revision = ESIF_TABLE_NO_REVISION;
}
#endif
}
static ESIF_INLINE void esif_acpi_set_cols(
struct esif_action_data *data_ptr,
const u32 count
)
{
#ifdef ESIF_ATTR_OS_WINDOWS
if (data_ptr->cols == 1)
data_ptr->cols = (u16)count;
#endif
#ifdef ESIF_ATTR_OS_LINUX
if (data_ptr->rows == 1)
data_ptr->rows = (u16)count;
else
data_ptr->cols = (u16)count;
#endif
}
static ESIF_INLINE u32 esif_ccb_acpi_pkg_count(union acpi_object *obj_ptr)
{
#ifdef ESIF_ATTR_OS_LINUX
return obj_ptr->package.count;
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* package.count in Windows is actually DataLength, not number of
* elements, so we need to walk thru the entire ACPI_METHOD_ARGUMENT to
* count how many are there
*/
union acpi_object *pkg_ptr =
(union acpi_object *)&obj_ptr->package.elements;
int pkg_len, obj_len = obj_ptr->package.count;
u32 count = 0;
while (obj_len > 0) {
/* Calc the size of each package and move to the next one */
/* make sure if the count is less than 4 to account for the */
/* union. A good example would be a short string like ma\0 */
pkg_len = (2 * sizeof(USHORT)) +
(pkg_ptr->package.count < sizeof(ULONG) ? sizeof(ULONG):
pkg_ptr->package.count);
pkg_ptr = (union acpi_object *)((u8 *)pkg_ptr + pkg_len);
obj_len -= pkg_len;
count++;
NO_ESIF_DEBUG(
"<object addr %p type %d len %d> "
"<pkg addr %p type %d len %d> count %d\n",
obj_ptr,
obj_ptr->package.type,
obj_ptr->package.count,
pkg_ptr,
pkg_ptr->package.type,
pkg_ptr->package.count,
count);
}
if (obj_len == 0) {
return count;
} else {
/* Don't count the last one which could be extra padding */
return count - 1;
}
#endif
}
static ESIF_INLINE union acpi_object
*esif_ccb_acpi_pkg_next(
union acpi_object *package,
union acpi_object *method,
u32 item
)
{
#ifdef ESIF_ATTR_OS_LINUX
return (union acpi_object *)&package->package.elements[item];
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
u32 offset;
UNREFERENCED_PARAMETER(package);
/*
* Windows: first element is actually Data[0], while the rest are
* (2 * sizeof(USHORT) + DataLength) also make sure if DataLength count is less than 4 to account for the union
*/
if (0 == item)
offset = 2 * sizeof(esif_acpi_p_type);
else
offset = (2 * sizeof(esif_acpi_p_type)) +
( method->string.length < sizeof(ULONG) ? sizeof(ULONG):
method->string.length);
NO_ESIF_DEBUG("orignal obj addr %p offset %ld, new addr %p\n",
method,
offset,
(u8 *)obj_ptr + offset);
return (union acpi_object *)((u8 *)method + offset);
#endif
}
/*
* ACPI Status/Failure
*/
static ESIF_INLINE int esif_ccb_has_acpi_failure(
acpi_status status,
struct acpi_buffer *buf_ptr
)
{
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* We check against STATUS_SUCCESS as the NTSTATUS from
* esif_ccb_acpi_evaluate_object is translated into an Linux AE code.
* STATUS_SUCCESS has the same value as AE_OK, which is 0.
*/
if (status != STATUS_SUCCESS)
return ESIF_TRUE;
/* buf_ptr could be NULL for SET operation */
if (buf_ptr && (buf_ptr->pointer == NULL || buf_ptr->length <= 0))
return ESIF_TRUE;
#endif
#ifdef ESIF_ATTR_OS_LINUX
if (ACPI_FAILURE(status))
return ESIF_TRUE;
#endif
return ESIF_FALSE;
}
#endif /* _ESIF_CCB_ACPI_H_ */
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,97 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_LF_CCB_GEN_ACTION_
#define _ESIF_LF_CCB_GEN_ACTION_
#include "esif_lf.h"
#ifdef ESIF_ATTR_OS_WINDOWS
#include "win\esif_lf_win_disp_intfc.h"
#include "win\esif_lf_win_gfx_intfc.h"
#include "win\esif_lf_os_win.h"
/* For ACTION ESIF_ACTION_DDIGFXDISP */
#define esif_get_action_ddigfxdisp(pLp, pPrim, pAct, pReq, pRsp) \
DispIntfcExecuteGetAction(pLp, pPrim, pAct, pReq, pRsp)
#define esif_set_action_ddigfxdisp(pLp, pPrim, pAct, pReq) \
DispIntfcExecuteSetAction(pLp, pPrim, pAct, pReq)
/* For ACTION ESIF_ACTION_DDIGFXPERF */
#define esif_get_action_ddigfxperf(pLp, pPrim, pAct, pReq, pRsp) \
GfxIntfcExecuteGetAction(pLp, pPrim, pAct, pReq, pRsp)
#define esif_set_action_ddigfxperf(pLp, pPrim, pAct, pReq) \
GfxIntfcExecuteSetAction(pLp, pPrim, pAct, pReq)
#define esif_get_action_code_putl(pUtil) \
esif_get_action_code_putl_win(pUtil)
#endif /* ESIF_ATTR_OS_WINDOWS */
#ifdef ESIF_ATTR_OS_LINUX
#define esif_get_action_ddigfxdisp(pLp, pPrim, pAct, pReq, pRsp) \
ESIF_E_ACTION_NOT_IMPLEMENTED
#define esif_set_action_ddigfxdisp(pLp, pPrim, pAct, pReq) \
ESIF_E_ACTION_NOT_IMPLEMENTED
#define esif_get_action_ddigfxperf(pLp, pPrim, pAct, pReq, pRsp) \
ESIF_E_ACTION_NOT_IMPLEMENTED
#define esif_set_action_ddigfxperf(pLp, pPrim, pAct, pReq) \
ESIF_E_ACTION_NOT_IMPLEMENTED
#define esif_get_action_code_putl(pUtil) \
ESIF_E_ACTION_NOT_IMPLEMENTED
#endif /* ESIF_ATTR_OS_LINUX */
#endif /* _ESIF_LF_CCB_GEN_ACTION_ */

View File

@@ -0,0 +1,195 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
/*
*
* Access to the message bus space is through the SoC Transaction Router’s PCI
* configuration registers.
* This unit relies on three 32-Bit PCI configuration registers to generate
* messages:
*
* Message Bus Control Register (MCR) - PCI[B:0,D:0,F:0] + D0h
* Message Data Register (MDR) - PCI[B:0,D:0,F:0] + D4h
* Message Control Register eXtension (MCRX) - PCI[B:0,D:0,F:0] + D8h
*
* This indirect access mode is similar to PCI CAM. Software uses the MCR/MCRX
* as an index register,
* indicating which message bus space register to access (MCRX only when
* required), and MDR as the data register.
* It writes to the MCR trigger message bus transactions.
*
* The format of MCR and MCRX are shown below. Most message bus registers are
* located in the SoC Transaction Router. The default opcode messages for those
* registers are as follows:
*
* MESSAGE OPCODES:
* Message ‘Read Register’ opcode: 0x10
* Message ‘Write Register’ opcode: 0x11
*
* Some ports may use other R/W opcodes 0x00/0x01 & 0x06/0x07.
*
* D0h MCR Message Control Register: A write to this register issues a message
* on the North Complex internal message network
* with the fields specified by that write data. All Byte enables must be
* enabled when writing this register.
*
* Bit Type Reset Description
* ----- ---- ----- -----------------
* 31:24 WO 00h Message Opcode
* 23:16 WO 00h Message Port
* 15:8 WO 00h Message Target Register Address
* 7:4 WO 0h Message Write Byte Enables: Active high Byte enables which
* enable each of the corresponding Bytes in the MDR when high.
* 3:0 WO 0h Reserved
*
* D4h MDR Message Data Register: Provides the means to specify data to be
* written or retrieving data that was read due
* to a message operation. For messages with a data payload, MDR must be written
* with the data to be sent prior to a write to MCR.
* For messages that return data, MDR contains the data read after the write to
* MCR completes.
*
* Bit Type Reset Description
* ----- ---- ----- -----------------------
* 31:0 RW 00h Message Data
*
* !!!!!! NOT SUPPORTED BY MBI.SYS Windows Driver or ESIF currently.
*
* D8h MCRX Offset/Register Extension: This is used for messages sent to end
* points that require more than 8 Bits for the offset/register.
* These Bits are a direct extension of MCR[15:8].
*
* Bit Type Reset Description
* ----- ---- ----- ------------------------
* 31:08 RW 00h Message Control Register Extension
* 7:0 RO 00h Reserved
*
* This handled by our companion driver but shown here for clarification.
*
* For Write:
* 1. Write Data to MDR
* 2. Write Upper Addr Bits to MCRX (Only if required)
* 3. Write Command to MCR = {Command (8Bits), PortId (8Bits), Offset (8Bits),
* ByteEnables (8Bits)}
*
* For Read:
* 1. Write Upper Addr Bits to MCRX (Only if required)
* 2. Write Command to MCR = {Command (8Bits), PortId (8Bits), Offset (8Bits),
* ByteEnables (8Bits)}
* 3. Read from MDR
*
*/
#ifndef _ESIF_LF_CCB_MBI_H_
#define _ESIF_LF_CCB_MBI_H_
#ifdef ESIF_ATTR_IOSF
#include <asm/iosf_mbi.h>
#endif
/* MBI Read 32 */
enum esif_rc esif_lf_win_mbi_read(u32 MCR, u32 *val_ptr);
static ESIF_INLINE enum esif_rc esif_ccb_mbi_read(
u8 port,
u8 punit,
u32 *val_ptr
)
{
#ifdef ESIF_ATTR_OS_WINDOWS
u32 MCR = 0x10000000 | (port << 16) | (punit << 8) | 0xF0;
return esif_lf_win_mbi_read(MCR, val_ptr);
#endif /* ESIF_ATTR_OS_WINDOWS */
#ifdef ESIF_ATTR_OS_LINUX
#ifdef ESIF_ATTR_IOSF
return iosf_mbi_read(port, 0x10, punit, val_ptr);
#else
*val_ptr = 0;
return ESIF_E_NOT_IMPLEMENTED;
#endif
#endif /* ESIF_ATTR_OS_LINUX */
}
/* MBI Write 32 */
enum esif_rc esif_lf_win_mbi_write(u32 MCR, u32 val);
static ESIF_INLINE enum esif_rc esif_ccb_mbi_write(
u8 port,
u32 punit,
u32 val
)
{
#ifdef ESIF_ATTR_OS_WINDOWS
u32 MCR = 0x11000000 | (port << 16) | (punit << 8) | 0xF0;
return esif_lf_win_mbi_write(MCR, val);
#endif /* ESIF_ATTR_OS_WINDOWS */
#ifdef ESIF_ATTR_OS_LINUX
#ifdef ESIF_ATTR_IOSF
return iosf_mbi_write(port, 0x11, punit, val);
#else
return ESIF_E_NOT_IMPLEMENTED;
#endif
#endif /* ESIF_ATTR_OS_LINUX */
}
#endif /* _ESIF_LF_CCB_MBI_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,110 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_CCB_MMIO_H_
#define _ESIF_CCB_MMIO_H_
#ifdef ESIF_ATTR_KERNEL
/* MMIO Read 32 */
static ESIF_INLINE void esif_ccb_mmio_read(
const void __iomem *base_addr,
u32 reg,
u32 *val_ptr
)
{
u8 *p = (u8 *)val_ptr;
int i = 0;
/*
* Don't just readl, it will fail to get 4-byte of TSTR0 where
* TSTR0 (offset 3, len 1) and TSTTP0 (offset 4, len 4)
*/
for (i = 0; i < 4; i++, p++) {
#ifdef ESIF_ATTR_OS_LINUX
*(u8 *)p = (readb(base_addr + reg + i));
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
*(u8 *)p = (READ_REGISTER_UCHAR((PUCHAR)base_addr + reg + i));
#endif
}
}
/* MMIO Write 32 */
static ESIF_INLINE void esif_ccb_mmio_write(
const void __iomem *base_addr,
u32 reg,
u32 val
)
{
u8 *p = (u8 *)&val;
int i = 0;
for (i = 0; i < 4; i++, p++) {
#ifdef ESIF_ATTR_OS_LINUX
writeb(*p, (void __iomem *)base_addr + reg + i);
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
WRITE_REGISTER_UCHAR((PUCHAR)base_addr + reg + i, *p);
#endif
}
}
#endif /* ESIF_ATTR_KERNEL */
#endif /* _ESIF_CCB_MMIO_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,200 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_CCB_MSR_H_
#define _ESIF_CCB_MSR_H_
#ifdef ESIF_ATTR_OS_WINDOWS
/* Windows Safe Function HELPERS */
/* Read MSR Helper returns 0 on success */
static ESIF_INLINE int esif_ccb_read_cpu_msr_safe(
const u8 cpu,
IN u32 p_msrAddress,
u32 *l,
u32 *h
)
{
__int64 int64Result = 0;
int status = 0;
KAFFINITY kaUserThreadAffinity = 0xff;
/* Save active processors and set affinity */
kaUserThreadAffinity = KeSetSystemAffinityThreadEx(((ULONG_PTR)1 << cpu));
/*
* EXCEPTION HANDLER
* If we read from an invalid MSR this will create an exception we catch
* it here to avoid the dreaded BSOD and use the exception to return an
* error code to our caller.
*/
try {
int64Result = __readmsr((int)p_msrAddress);
}
except(EXCEPTION_EXECUTE_HANDLER) {
status = 1;
goto exit;
}
*l = (ULONG)(int64Result & 0xFFFFFFFF);
*h = (LONG)((int64Result >> 32) & 0xFFFFFFFF);
exit:
KeRevertToUserAffinityThreadEx(kaUserThreadAffinity);
return status;
}
/* Write MSR Helper returns 0 on success */
static ESIF_INLINE int esif_ccb_write_cpu_msr_safe(
const u8 cpu,
IN ULONG p_msrAddress,
u32 l,
u32 h
)
{
__int64 int64Content = 0;
int status = 0;
KAFFINITY kaUserThreadAffinity = 0xff;
int64Content = h;
int64Content = int64Content << 32;
int64Content |= l;
/* Save active processors and set affinity */
kaUserThreadAffinity = KeSetSystemAffinityThreadEx(((ULONG_PTR)1 << cpu));
/*
* EXCEPTION HANDLER
* If we read from an invalid MSR this will create an exception we catch
* it here to avoid the dreaded BSOD and use the exception to return an
* error code to our caller.
*/
try {
__writemsr(p_msrAddress, int64Content);
}
except(EXCEPTION_EXECUTE_HANDLER) {
status = 1;
}
KeRevertToUserAffinityThreadEx(kaUserThreadAffinity);
return status;
}
static ESIF_INLINE u64 esif_ccb_get_online_cpu(void)
{
return (u64)KeQueryActiveProcessors();
}
#endif
#ifdef ESIF_ATTR_OS_LINUX
static ESIF_INLINE u64 esif_ccb_get_online_cpu(void)
{
u64 online_cpus = 0;
int i;
for_each_online_cpu(i)
online_cpus = online_cpus | (1UL << i);
return online_cpus;
}
#endif
/* Read MSR */
static ESIF_INLINE int esif_ccb_read_msr(
const u8 cpu,
const u32 msr,
u64 *val_ptr
)
{
int rc = 0;
u32 l = 0;
u32 h = 0;
#ifdef ESIF_ATTR_OS_LINUX
rc = rdmsr_safe_on_cpu(cpu, msr, &l, &h);
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
rc = esif_ccb_read_cpu_msr_safe(cpu, msr, &l, &h);
#endif
*val_ptr = (((u64)h << 32) | l);
return rc;
}
/* Write MSR */
static ESIF_INLINE int esif_ccb_write_msr(
const u8 cpu,
const u32 msr,
const u64 val
)
{
u32 l = (u32)val, h = (u32)(val >> 32);
#ifdef ESIF_ATTR_OS_LINUX
return wrmsr_safe_on_cpu(cpu, msr, l, h);
#endif
#ifdef ESIF_ATTR_OS_WINDOWS
return esif_ccb_write_cpu_msr_safe(cpu, msr, l, h);
#endif
}
#endif /* _ESIF_CCB_MSR_H_ */
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,591 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_ipc.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified
* against Windows SDK/DDK included headers which we have no control over.
*
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
/* Debug Logging Defintions */
#define INIT_DEBUG 0 /* Init Debug */
#define COMMAND_DEBUG 1 /* Command Debug */
#define DECODE_DEBUG 2 /* Decode Debug */
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_COMMAND, \
INIT_DEBUG, \
format, \
##__VA_ARGS__)
#define ESIF_TRACE_DYN_COMMAND(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_COMMAND, \
COMMAND_DEBUG, \
format, \
##__VA_ARGS__)
#define ESIF_TRACE_DYN_DECODE(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_COMMAND, \
DECODE_DEBUG, \
format, \
##__VA_ARGS__)
/*
******************************************************************************
* PRIVATE
******************************************************************************
*/
/* Set Debug Modules */
static void esif_execute_ipc_command_set_debug_modules(
struct esif_ipc_command *command_ptr
)
{
/* Sanity Check */
if (ESIF_DATA_UINT32 == command_ptr->req_data_type &&
0 == command_ptr->req_data_offset &&
sizeof(struct esif_command_debug_modules) ==
command_ptr->req_data_len) {
struct esif_command_debug_modules *data_ptr =
(struct esif_command_debug_modules *)(command_ptr + 1);
ESIF_TRACE_DYN_COMMAND(
"%s: ESIF_COMMAND_TYPE_SET_DEBUG_MODULES "
"Modules: 0x%08X\n",
ESIF_FUNC,
data_ptr->modules);
esif_debug_set_modules(data_ptr->modules);
command_ptr->return_code = ESIF_OK;
}
}
/* Set Debug Module Level */
static void esif_execute_ipc_command_set_debug_module_level(
struct esif_ipc_command *command_ptr
)
{
/* Sanity Check */
if (ESIF_DATA_STRUCTURE == command_ptr->req_data_type &&
0 == command_ptr->req_data_offset &&
sizeof(struct esif_command_set_debug_module_level) ==
command_ptr->req_data_len) {
struct esif_command_set_debug_module_level *data_ptr =
(struct esif_command_set_debug_module_level *)
(command_ptr + 1);
ESIF_TRACE_DYN_COMMAND(
"%s: ESIF_COMMAND_TYPE_SET_DEBUG_MODULE_LEVEL "
"Module: %d Level: 0x%08X\n",
ESIF_FUNC,
data_ptr->module,
data_ptr->level);
esif_debug_set_module_category(data_ptr->module,
data_ptr->level);
command_ptr->return_code = ESIF_OK;
}
}
/* Get Debug Module Level */
static void esif_execute_ipc_command_get_debug_module_level(
struct esif_ipc_command *command_ptr
)
{
/* Sanity Check */
if (ESIF_DATA_STRUCTURE == command_ptr->rsp_data_type &&
0 == command_ptr->rsp_data_offset &&
sizeof(struct esif_command_get_debug_module_level) ==
command_ptr->rsp_data_len) {
struct esif_command_get_debug_module_level *data_ptr =
(struct esif_command_get_debug_module_level *)
(command_ptr + 1);
data_ptr->modules = g_esif_module_mask;
esif_ccb_memcpy(&data_ptr->levels,
&g_esif_module_category_mask,
sizeof(g_esif_module_category_mask));
data_ptr->tracelevel = g_esif_trace_level;
ESIF_TRACE_DYN_COMMAND(
"%s: ESIF_COMMAND_TYPE_GET_DEBUG_MODULE_LEVEL "
"modules 0x%08X\n",
ESIF_FUNC,
data_ptr->modules);
command_ptr->return_code = ESIF_OK;
}
}
/* Get Kernel Information */
static void esif_execute_ipc_command_get_kernel_info(
struct esif_ipc_command *command_ptr
)
{
/* Sanity Check */
if (ESIF_DATA_STRUCTURE == command_ptr->rsp_data_type &&
0 == command_ptr->rsp_data_offset &&
sizeof(struct esif_command_get_kernel_info) ==
command_ptr->rsp_data_len) {
struct esif_command_get_kernel_info *data_ptr =
(struct esif_command_get_kernel_info *)
(command_ptr + 1);
esif_ccb_strcpy(data_ptr->ver_str, ESIF_VERSION, ESIF_NAME_LEN);
ESIF_TRACE_DYN_COMMAND(
"%s: ESIF_COMMAND_TYPE_GET_KERNEL_INFO\n",
ESIF_FUNC);
command_ptr->return_code = ESIF_OK;
}
}
/* Get Kernel Information */
static void esif_execute_ipc_command_get_memory_stats(
struct esif_ipc_command *command_ptr
)
{
/* Sanity Check */
if (ESIF_DATA_STRUCTURE == command_ptr->rsp_data_type &&
0 == command_ptr->rsp_data_offset &&
sizeof(struct esif_command_get_memory_stats) ==
command_ptr->rsp_data_len) {
struct esif_command_get_memory_stats *data_ptr =
(struct esif_command_get_memory_stats *)
(command_ptr + 1);
u32 reset = *(u32 *)data_ptr;
if (reset) {
esif_ccb_memset(&data_ptr->stats, 0,
sizeof(struct esif_memory_stats));
esif_ccb_write_lock(&g_memstat_lock);
esif_ccb_memset(&g_memstat, 0,
sizeof(struct esif_memory_stats));
esif_ccb_write_unlock(&g_memstat_lock);
} else {
int i = 0;
esif_ccb_read_lock(&g_memstat_lock);
esif_ccb_memcpy(&data_ptr->stats, &g_memstat,
sizeof(struct esif_memory_stats));
esif_ccb_read_unlock(&g_memstat_lock);
esif_ccb_read_lock(&g_mempool_lock);
for (i = 0; i < ESIF_MEMPOOL_TYPE_MAX; i++) {
if (NULL == g_mempool[i])
continue; /* Skip Unused */
esif_ccb_strcpy(data_ptr->mempool_stat[i].name,
g_mempool[i]->name_ptr,
ESIF_NAME_LEN);
data_ptr->mempool_stat[i].pool_tag =
g_mempool[i]->pool_tag;
data_ptr->mempool_stat[i].object_size =
g_mempool[i]->object_size;
data_ptr->mempool_stat[i].alloc_count =
g_mempool[i]->alloc_count;
data_ptr->mempool_stat[i].free_count =
g_mempool[i]->free_count;
}
esif_ccb_read_unlock(&g_mempool_lock);
esif_ccb_read_lock(&g_memtype_lock);
for (i = 0; i < ESIF_MEMTYPE_TYPE_MAX; i++) {
if (NULL == g_memtype[i])
continue; /* Skip Unused */
esif_ccb_strcpy(data_ptr->memtype_stat[i].name,
g_memtype[i]->name_ptr,
ESIF_NAME_LEN);
data_ptr->memtype_stat[i].pool_tag =
g_memtype[i]->type_tag;
data_ptr->memtype_stat[i].alloc_count =
g_memtype[i]->alloc_count;
data_ptr->memtype_stat[i].free_count =
g_memtype[i]->free_count;
}
esif_ccb_read_unlock(&g_memtype_lock);
}
ESIF_TRACE_DYN_COMMAND(
"%s: ESIF_COMMAND_TYPE_GET_MEMORY_STATS reset %d\n",
ESIF_FUNC,
reset);
command_ptr->return_code = ESIF_OK;
}
}
/* Get Participants */
static void esif_execute_ipc_command_get_participants(
struct esif_ipc_command *command_ptr
)
{
/* Sanity Check */
if (ESIF_DATA_STRUCTURE == command_ptr->rsp_data_type &&
0 == command_ptr->rsp_data_offset &&
sizeof(struct esif_command_get_participants) ==
command_ptr->rsp_data_len) {
u8 i = 0;
struct esif_command_get_participants *data_ptr =
(struct esif_command_get_participants *)
(command_ptr + 1);
ESIF_TRACE_DYN_COMMAND(
"%s: ESIF_COMMAND_TYPE_GET_PARTICIPANTS\n",
ESIF_FUNC);
for (i = 0; i < MAX_PARTICIPANT_ENTRY; i++) {
struct esif_lp *lp_ptr =
esif_lf_pm_lp_get_by_instance_id(i);
if (NULL != lp_ptr) {
data_ptr->participant_info[i].id = i;
esif_ccb_strcpy(
data_ptr->participant_info[i].name,
lp_ptr->pi_ptr->name,
ESIF_NAME_LEN);
esif_ccb_strcpy(
data_ptr->participant_info[i].desc,
lp_ptr->pi_ptr->desc,
ESIF_DESC_LEN);
esif_ccb_memcpy(
data_ptr->participant_info[i].class_guid,
lp_ptr->pi_ptr->class_guid,
ESIF_GUID_LEN);
data_ptr->participant_info[i].version =
lp_ptr->pi_ptr->version;
data_ptr->participant_info[i].bus_enum =
lp_ptr->pi_ptr->enumerator;
data_ptr->participant_info[i].state =
esif_lf_pm_lp_get_state(lp_ptr);
if (NULL != lp_ptr->dsp_ptr) {
esif_ccb_strcpy(
data_ptr->participant_info[i].dsp_code,
lp_ptr->dsp_ptr->get_code(
lp_ptr->dsp_ptr),
ESIF_DSP_NAME_LEN);
data_ptr->participant_info[i].dsp_ver_major =
lp_ptr->dsp_ptr->get_ver_major(
lp_ptr->dsp_ptr);
data_ptr->participant_info[i].
dsp_ver_minor =
lp_ptr->dsp_ptr->get_ver_minor(
lp_ptr->dsp_ptr);
}
} else {
data_ptr->participant_info[i].id = i;
if (1 == i) {
esif_ccb_strcpy(
data_ptr->participant_info[i].desc,
"RESERVED",
ESIF_DESC_LEN);
} else {
}
}
}
data_ptr->count = i;
command_ptr->return_code = ESIF_OK;
}
}
/* Get Participant */
static void esif_execute_ipc_command_get_participant_detail(
struct esif_ipc_command *command_ptr
)
{
/* Sanity Check */
if (ESIF_DATA_STRUCTURE == command_ptr->rsp_data_type &&
0 == command_ptr->rsp_data_offset &&
sizeof(struct esif_command_get_participant_detail) ==
command_ptr->rsp_data_len) {
struct esif_command_get_participant_detail *data_ptr =
(struct esif_command_get_participant_detail *)(
command_ptr + 1);
/* ID Will Be In Buffer ON Arrival */
u32 participant_id = *(u32 *) data_ptr;
ESIF_TRACE_DYN_COMMAND(
"%s: ESIF_COMMAND_TYPE_PARTICIPANT_DETAIL id %d\n",
ESIF_FUNC,
participant_id);
{
struct esif_lp *lp_ptr =
esif_lf_pm_lp_get_by_instance_id((u8)participant_id);
if (NULL != lp_ptr) {
/* Participant Info */
data_ptr->id = participant_id;
data_ptr->version = lp_ptr->pi_ptr->version;
data_ptr->enumerator =
lp_ptr->pi_ptr->enumerator;
esif_ccb_strcpy(data_ptr->name,
lp_ptr->pi_ptr->name,
ESIF_NAME_LEN);
esif_ccb_strcpy(data_ptr->desc,
lp_ptr->pi_ptr->desc,
ESIF_DESC_LEN);
esif_ccb_strcpy(data_ptr->driver_name,
lp_ptr->pi_ptr->driver_name,
ESIF_NAME_LEN);
esif_ccb_strcpy(data_ptr->device_name,
lp_ptr->pi_ptr->device_name,
ESIF_NAME_LEN);
esif_ccb_strcpy(data_ptr->device_path,
lp_ptr->pi_ptr->device_path,
ESIF_PATH_LEN);
esif_ccb_memcpy(data_ptr->class_guid,
lp_ptr->pi_ptr->class_guid,
ESIF_GUID_LEN);
data_ptr->flags = lp_ptr->pi_ptr->flags;
/* ACPI */
esif_ccb_strcpy(data_ptr->acpi_device,
lp_ptr->pi_ptr->acpi_device,
ESIF_NAME_LEN);
esif_ccb_strcpy(data_ptr->acpi_scope,
lp_ptr->pi_ptr->acpi_scope,
ESIF_SCOPE_LEN);
esif_ccb_strcpy(data_ptr->acpi_uid,
lp_ptr->pi_ptr->acpi_uid,
sizeof(data_ptr->acpi_uid));
data_ptr->acpi_type = lp_ptr->pi_ptr->acpi_type;
/* PCI */
data_ptr->pci_vendor =
(u16)lp_ptr->pi_ptr->pci_vendor;
data_ptr->pci_device =
(u16)lp_ptr->pi_ptr->pci_device;
data_ptr->pci_bus =
lp_ptr->pi_ptr->pci_bus;
data_ptr->pci_bus_device =
lp_ptr->pi_ptr->pci_bus_device;
data_ptr->pci_function =
lp_ptr->pi_ptr->pci_function;
data_ptr->pci_revision =
lp_ptr->pi_ptr->pci_revision;
data_ptr->pci_class =
lp_ptr->pi_ptr->pci_class;
data_ptr->pci_sub_class =
lp_ptr->pi_ptr->pci_sub_class;
data_ptr->pci_prog_if =
lp_ptr->pi_ptr->pci_prog_if;
/* LP */
data_ptr->state =
esif_lf_pm_lp_get_state(lp_ptr);
data_ptr->timer_period =
lp_ptr->domains[0].timer_period_msec;
if (NULL != lp_ptr->dsp_ptr) {
/* Have DSP */
data_ptr->have_dsp = 1;
esif_ccb_strcpy(data_ptr->dsp_code,
lp_ptr->dsp_ptr->get_code(
lp_ptr->dsp_ptr),
ESIF_DSP_NAME_LEN);
data_ptr->dsp_ver_major =
lp_ptr->dsp_ptr->get_ver_major(
lp_ptr->dsp_ptr);
data_ptr->dsp_ver_minor =
lp_ptr->dsp_ptr->get_ver_minor(
lp_ptr->dsp_ptr);
if (NULL != lp_ptr->dsp_ptr->cpc_ptr) {
/* Have CPC */
data_ptr->have_cpc = 1;
data_ptr->cpc_version =
lp_ptr->dsp_ptr->cpc_ptr->header.version;
data_ptr->cpc_signature =
lp_ptr->dsp_ptr->cpc_ptr->header.cpc.signature;
data_ptr->cpc_size =
lp_ptr->dsp_ptr->cpc_ptr->size;
data_ptr->cpc_primitive_count =
lp_ptr->dsp_ptr->cpc_ptr->number_of_basic_primitives;
} /* cpc */
} /* dsp */
} /* lp */
} /* block */
command_ptr->return_code = ESIF_OK;
} /* if */
}
/* Dispatch */
struct esif_ipc *esif_execute_ipc_command(
struct esif_ipc *ipc_ptr
)
{
struct esif_ipc_command *command_ptr =
(struct esif_ipc_command *)(ipc_ptr + 1);
u32 data_size = 0;
command_ptr->return_code = ESIF_E_COMMAND_DATA_INVALID;
if (ESIF_COMMAND_VERSION != command_ptr->version)
goto exit;
data_size = ipc_ptr->data_len - sizeof(*command_ptr);
if(((command_ptr->req_data_offset + command_ptr->req_data_len) >
data_size) ||
((command_ptr->rsp_data_offset + command_ptr->rsp_data_len) >
data_size))
goto exit;
ESIF_TRACE_DYN_COMMAND("%s: COMMAND Received: ipc %p\n",
ESIF_FUNC,
ipc_ptr);
ESIF_TRACE_DYN_DECODE(" Version: %d\n"
" Type: %s(%d)\n"
" Priority: %s(%d)\n"
" Payload Length: %d\n"
" Request Data Type: %s(%d)\n"
" Request Data Offset: %d\n"
" Request Data Length: %d\n"
" Response Data Type: %s(%d)\n"
" Response Data Offset: %d\n"
" Response Data Length: %d\n",
(int)command_ptr->version,
esif_command_type_str(command_ptr->type),
(int)command_ptr->type,
esif_command_priority_str(command_ptr->priority),
(int)command_ptr->priority,
(int)command_ptr->payload_len,
esif_data_type_str(command_ptr->req_data_type),
(int)command_ptr->req_data_type,
(int)command_ptr->req_data_offset,
(int)command_ptr->req_data_len,
esif_data_type_str(command_ptr->rsp_data_type),
(int)command_ptr->rsp_data_type,
(int)command_ptr->rsp_data_offset,
(int)command_ptr->rsp_data_len);
switch (command_ptr->type) {
case ESIF_COMMAND_TYPE_SET_DEBUG_MODULES:
esif_execute_ipc_command_set_debug_modules(command_ptr);
break;
case ESIF_COMMAND_TYPE_SET_DEBUG_MODULE_LEVEL:
esif_execute_ipc_command_set_debug_module_level(command_ptr);
break;
case ESIF_COMMAND_TYPE_GET_DEBUG_MODULE_LEVEL:
esif_execute_ipc_command_get_debug_module_level(command_ptr);
break;
case ESIF_COMMAND_TYPE_GET_KERNEL_INFO:
esif_execute_ipc_command_get_kernel_info(command_ptr);
break;
case ESIF_COMMAND_TYPE_GET_MEMORY_STATS:
esif_execute_ipc_command_get_memory_stats(command_ptr);
break;
case ESIF_COMMAND_TYPE_GET_PARTICIPANTS:
esif_execute_ipc_command_get_participants(command_ptr);
break;
case ESIF_COMMAND_TYPE_GET_PARTICIPANT_DETAIL:
esif_execute_ipc_command_get_participant_detail(command_ptr);
break;
default:
ESIF_TRACE_DYN_COMMAND("%s: Unknown Command Type %d:\n",
ESIF_FUNC, command_ptr->type);
break;
}
ESIF_TRACE_DYN_COMMAND("%s: COMMAND return result: %s(%d)\n", ESIF_FUNC,
esif_rc_str(
command_ptr->return_code),
command_ptr->return_code);
exit:
/* Send To User */
return ipc_ptr;
}
/* Init */
enum esif_rc esif_command_init(void)
{
ESIF_TRACE_DYN_INIT("%s: Initialize Command\n", ESIF_FUNC);
return ESIF_OK;
}
/* Exit */
void esif_command_exit(void)
{
ESIF_TRACE_DYN_INIT("%s: Exit Command\n", ESIF_FUNC);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,332 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif.h"
#include "esif_cpc.h"
#include "esif_lf_domain.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified
* against Windows SDK/DDK included headers which we have no control over.
*
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
/* Debug Logging Defintions */
#define INIT_DEBUG 0
#define CPC_DEBUG 1
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_CPC, INIT_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_CPC(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_CPC, CPC_DEBUG, format, ##__VA_ARGS__)
/*
******************************************************************************
* PRIVATE
******************************************************************************
*/
/* Assumes hash table has already been created */
static enum esif_rc esif_cpc_to_dsp(struct esif_lp_dsp *dsp_ptr)
{
struct esif_lp_cpc *cpc_ptr = dsp_ptr->cpc_ptr;
struct esif_cpc_primitive *primitive_ptr = NULL;
struct esif_cpc_algorithm *algorithm_ptr;
struct esif_cpc_event *event_ptr;
struct domain *domain_ptr;
enum esif_rc rc = ESIF_OK;
u32 i;
u8 *base_ptr;
u64 offset;
base_ptr = (u8 *)cpc_ptr;
dsp_ptr->code_ptr = (esif_string)cpc_ptr->header.code;
dsp_ptr->domain_count_ptr = (u8 *)&cpc_ptr->number_of_domains;
dsp_ptr->ver_major_ptr = (u8 *)&cpc_ptr->header.ver_major;
dsp_ptr->ver_minor_ptr = (u8 *)&cpc_ptr->header.ver_minor;
dsp_ptr->capability_ptr = (esif_flags_t *)
&cpc_ptr->header.cpc.capability;
ESIF_TRACE_DYN_CPC(
"%s: <cpc @ %p> CPC name '%s' size %d num_primitives %u, num_algorithms %u, num_domains %u\n",
ESIF_FUNC,
cpc_ptr,
cpc_ptr->header.code,
cpc_ptr->size,
cpc_ptr->number_of_basic_primitives,
cpc_ptr->number_of_algorithms,
*dsp_ptr->domain_count_ptr);
/* 1. Insert All Primitives Into Hash */
/* Locate First Primitive Laid After CPC Struct */
primitive_ptr =
(struct esif_cpc_primitive *)((u8 *)cpc_ptr +
sizeof(struct esif_lp_cpc));
for (i = 0; i < cpc_ptr->number_of_basic_primitives; i++) {
offset = (u64)((u8 *)primitive_ptr - base_ptr);
ESIF_TRACE_DYN_CPC(
"<%06llu> Primitive[%03d]: size %03d tuple <%03u %03u %03u> operation %u(%s) num_actions %d\n",
offset,
i,
primitive_ptr->size,
primitive_ptr->tuple.id,
primitive_ptr->tuple.domain,
primitive_ptr->tuple.instance,
primitive_ptr->operation,
esif_primitive_opcode_str(
(enum esif_primitive_opcode)
primitive_ptr->operation),
primitive_ptr->number_of_actions);
/* Must Be ESIF Primitive Not CPC Primitive Format */
rc = dsp_ptr->insert_primitive(dsp_ptr, primitive_ptr);
if (ESIF_OK != rc)
goto exit;
/* Primitives Have Varaible Length Due To Number Of Actions */
primitive_ptr =
(struct esif_cpc_primitive *)((u8 *)primitive_ptr +
primitive_ptr->size);
}
/* 2. Insert All Algorithms Into Linked List */
/* First Algorithm Laid After the Last Primitive */
algorithm_ptr = (struct esif_cpc_algorithm *)primitive_ptr;
for (i = 0; i < cpc_ptr->number_of_algorithms; i++) {
offset = (u64)((u8 *)algorithm_ptr - base_ptr);
ESIF_TRACE_DYN_CPC("<%06llu> Algorithm[%3d]: action_type %u(%s) temp_xform %u tempC1 %u tempC2 %u size %u\n",
offset,
i,
algorithm_ptr->action_type,
esif_action_type_str(
(enum esif_action_type)algorithm_ptr
->action_type),
algorithm_ptr->temp_xform,
algorithm_ptr->tempC1,
algorithm_ptr->tempC2,
algorithm_ptr->size);
rc = dsp_ptr->insert_algorithm(dsp_ptr, algorithm_ptr);
if (ESIF_OK != rc)
goto exit;
/* Next Algorithm. Algorithms Are Fix-Sized */
algorithm_ptr++;
}
/* Truncate any unsupported domain conunts */
if (*dsp_ptr->domain_count_ptr > ESIF_DOMAIN_MAX)
*dsp_ptr->domain_count_ptr = ESIF_DOMAIN_MAX;
/* Domains are contained in an array one entry per domain */
if (*dsp_ptr->domain_count_ptr > 0) {
dsp_ptr->domains_ptr = (struct domain *)algorithm_ptr;
ESIF_TRACE_DYN_CPC("%s: First DWORD %08x\n",
ESIF_FUNC,
*(u32 *)dsp_ptr->domains_ptr);
}
/* Domain */
domain_ptr = (struct domain *)algorithm_ptr;
for (i = 0; i < cpc_ptr->number_of_domains; i++) {
offset = (u64)((u8 *)domain_ptr - base_ptr);
ESIF_TRACE_DYN_CPC("<%06llu> domain size %d name %s\n",
offset,
domain_ptr->size,
domain_ptr->descriptor.name);
domain_ptr =
(struct domain *)((u8 *)domain_ptr + domain_ptr->size);
}
/* Event */
event_ptr = (struct esif_cpc_event *)domain_ptr;
for (i = 0; i < cpc_ptr->number_of_events; i++) {
offset = (u64)((u8 *)event_ptr - base_ptr);
ESIF_TRACE_DYN_CPC(
"<%06llu> name %s notify %x esif_event %s(%d) esif_event_group TBD(%d)\n",
offset,
event_ptr->name,
event_ptr->event_key[i],
esif_event_type_str(event_ptr->esif_event),
event_ptr->esif_event,
event_ptr->esif_group);
/* Todo Handle Other Types Here */
if (ESIF_EVENT_GROUP_ACPI == event_ptr->esif_group) {
rc = dsp_ptr->insert_event(dsp_ptr, event_ptr);
if (ESIF_OK != rc)
goto exit;
}
/* Next Event. Events Are Fix-Sized */
event_ptr++;
}
exit:
ESIF_TRACE_DYN_CPC(
"%s: %u primitives, %u algorithms and %u events inserted, status %s! %u domain found\n",
ESIF_FUNC,
cpc_ptr->number_of_basic_primitives,
cpc_ptr->number_of_algorithms,
cpc_ptr->number_of_events,
esif_rc_str(rc),
cpc_ptr->number_of_domains);
return rc;
}
/*
******************************************************************************
* PUBLIC
******************************************************************************
*/
/* CPC Unpack */
enum esif_rc esif_cpc_unpack(
struct esif_lp_dsp *dsp_ptr,
const struct esif_data *req_data_ptr
)
{
struct esif_lp_cpc *cpc_ptr = NULL;
struct esif_cpc_header *cpc_header_ptr = NULL;
ESIF_TRACE_DYN_CPC("%s: START\n", ESIF_FUNC);
ESIF_TRACE_DYN_CPC("%s: dsp %p req_data %p cpc %p size %d\n",
ESIF_FUNC,
dsp_ptr,
req_data_ptr,
req_data_ptr->buf_ptr,
req_data_ptr->buf_len);
/* Validate Thourougly Here */
if (req_data_ptr->type != ESIF_DATA_DSP)
return ESIF_E_INVALID_REQUEST_TYPE;
if (req_data_ptr->buf_len < sizeof(struct esif_cpc_header))
return ESIF_E_CPC_SHORT;
cpc_ptr = (struct esif_lp_cpc *)req_data_ptr->buf_ptr;
cpc_header_ptr = (struct esif_cpc_header *)&cpc_ptr->header;
ESIF_TRACE_DYN_CPC(
"%s: code %s ver %x (%x,%x), signature %08x, version %x\n",
ESIF_FUNC,
cpc_header_ptr->code,
cpc_header_ptr->version,
cpc_header_ptr->ver_major,
cpc_header_ptr->ver_minor,
cpc_header_ptr->cpc.signature,
cpc_header_ptr->cpc.version);
if (cpc_header_ptr->cpc.signature != *(unsigned int *)"@CPC")
return ESIF_E_CPC_SIGNATURE;
/* Make a copy for now */
cpc_ptr = (struct esif_lp_cpc *)esif_ccb_malloc(req_data_ptr->buf_len);
if (NULL != cpc_ptr) {
esif_ccb_memcpy(cpc_ptr,
req_data_ptr->buf_ptr,
req_data_ptr->buf_len);
dsp_ptr->cpc_ptr = cpc_ptr;
esif_cpc_to_dsp(dsp_ptr);
}
ESIF_TRACE_DYN_CPC(" %s: STOP\n", ESIF_FUNC);
return ESIF_OK;
}
/* CPC Free */
void esif_cpc_free(struct esif_lp_dsp *dsp_ptr)
{
ESIF_TRACE_DYN_CPC("%s: START\n", ESIF_FUNC);
if (NULL == dsp_ptr || NULL == dsp_ptr->cpc_ptr)
return;
esif_ccb_free(dsp_ptr->cpc_ptr);
dsp_ptr->cpc_ptr = NULL;
ESIF_TRACE_DYN_CPC("%s: STOP\n", ESIF_FUNC);
}
/* Init */
enum esif_rc esif_cpc_init(void)
{
ESIF_TRACE_DYN_INIT("%s: Initialize Compact Primitive Catalog(CPC)\n",
ESIF_FUNC);
return ESIF_OK;
}
/* Exit */
void esif_cpc_exit(void)
{
ESIF_TRACE_DYN_INIT("%s: UnInitialize Compact Primitive Catalog(CPC)\n",
ESIF_FUNC);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,157 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified against Windows SDK/DDK included headers which we
* have no control over.
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
/* Debug Logging Defintions */
#define INIT_DEBUG 0
#define DATA_DEBUG 1
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_DATA, INIT_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_DATA(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_DATA, DATA_DEBUG, format, ##__VA_ARGS__)
/*
** Agnostic
*/
/* Allocate Data */
struct esif_data *esif_data_alloc(
enum esif_data_type type,
u32 data_len
)
{
struct esif_data *data_ptr = NULL;
data_ptr = esif_ccb_mempool_zalloc(ESIF_MEMPOOL_TYPE_DATA);
if (NULL == data_ptr)
return NULL;
data_ptr->type = type;
data_ptr->buf_len = data_len;
if (data_len > 0) {
data_ptr->buf_ptr = esif_ccb_malloc(data_len);
if (NULL == data_ptr->buf_ptr) {
esif_ccb_mempool_free(ESIF_MEMPOOL_TYPE_DATA, data_ptr);
return NULL;
}
} else {
ESIF_TRACE_DYN_DATA(
"%s: 0 Length Requesed WARNING Caller Must Allocate "
"Buffer\n",
ESIF_FUNC);
}
ESIF_TRACE_DYN_DATA("%s: type = %d, buf_len = %d, buf_ptr = %p\n",
ESIF_FUNC,
data_ptr->type,
(int)data_ptr->buf_len,
data_ptr->buf_ptr);
return data_ptr;
}
/* Free Data */
void esif_data_free(
struct esif_data *data_ptr
)
{
if (NULL == data_ptr)
return;
/* Free Buffer If Any */
if (NULL != data_ptr->buf_ptr)
esif_ccb_free(data_ptr->buf_ptr);
esif_ccb_mempool_free(ESIF_MEMPOOL_TYPE_DATA, data_ptr);
}
/* Init */
enum esif_rc esif_data_init(void)
{
struct esif_ccb_mempool *mempool_ptr = NULL;
ESIF_TRACE_DYN_DATA("%s: Initialize Data\n", ESIF_FUNC);
mempool_ptr = esif_ccb_mempool_create(ESIF_MEMPOOL_TYPE_DATA,
ESIF_MEMPOOL_FW_DATA,
sizeof(struct esif_data));
if (NULL == mempool_ptr)
return ESIF_E_NO_MEMORY;
return ESIF_OK;
}
/* Exit */
void esif_data_exit(void)
{
ESIF_TRACE_DYN_DATA("%s: Exit Data\n", ESIF_FUNC);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,152 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_DOMAIN_H_
#define _ESIF_DOMAIN_H_
#include "esif.h"
/*
** Domain
*/
#define ESIF_DOMAIN_VERSION 0x1
#define ESIF_DOMAIN_MAX 10
#define ESIF_DOMAIN_TEMP_INVALID 0xffffffff
/* Translate Qualifier To Index */
static ESIF_INLINE enum esif_rc esif_lp_domain_index (
u16 domain,
u8 *index
)
{
enum esif_rc rc = ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS;
u8 indexVal;
if ((domain & 0xFF) != 'D')
goto exit;
indexVal = (u8)(domain >> 8);
if ((indexVal < '0') || ('9' < indexVal))
goto exit;
indexVal &= 0x0F;
*index = indexVal;
rc = ESIF_OK;
exit:
return rc;
}
struct esif_lp_domain {
u8 instance; /* Instance */
esif_flags_t capabilities; /* Capabilities */
enum esif_domain_type domainType; /* Domain Type */
u16 id; /* Domain ID */
char *name_ptr; /* Name */
char *desc_ptr; /* Describe Qualifier */
struct esif_lp *lp_ptr; /* Lower Participant Back Ref
* */
/* ESIF will only poll when it has to otherwise it will utilize hardware
** provided programmable thresholds and notifications but if it has no
** other method it will poll.
*/
u8 poll; /* Is Polling? */
esif_flags_t poll_mask; /* Want To Poll? */
/* Timer For Polling */
esif_ccb_timer_t timer; /* Periodic Work Timer */
u32 timer_period_msec; /* Periodic Interval */
/* RAPL / Power */
u32 rapl_energy_units_current; /* Last energy accumulator read */
u32 rapl_energy_units_last; /* Read before for calc delta */
u32 rapl_energy_units_per_sec; /* Actual Energy Units Used Per Sec */
u32 rapl_power; /* Calculated Power */
/* Temperature Thresholds */
esif_temp_t temp_cache0; /* Cache Lower */
esif_temp_t temp_cache1; /* Cache Upper */
esif_temp_t temp_aux0; /* Lower */
/* enum esif_lp_domain_th_state temp_aux0_state; / * state machine
* state * / */
esif_temp_t temp_aux1; /* Upper */
/* enum esif_lp_domain_th_state temp_aux1_state; / * State machine
* state * / */
esif_temp_t temp_hysteresis; /* Lower Hysteresis */
/* Power Thresholds */
esif_power_t power_aux0; /* Lower */
esif_power_t power_aux1; /* Upper */
esif_power_t power_hysteresis; /* Lower Hysteresis */
/* Unit Data */
esif_temp_t temp_tjmax; /* Tjmax */
esif_power_t unit_power; /* Power Unit */
esif_power_t unit_energy; /* Energt Unit */
u32 unit_time; /* Time Unit */
#ifdef ESIF_ATTR_OS_LINUX
struct device device; /* Lower Participant Qualifier Class Device */
struct thermal_zone_device *tzd_ptr; /* Thermal Zone Device If Any */
struct thermal_cooling_device *cdev_ptr; /* Cooling Device If Any */
#endif
};
#endif /* _ESIF_DOMAIN_H_ */
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,792 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_lf.h"
#include "esif_dsp.h"
#include "esif_hash_table.h"
#include "esif_lf_action.h"
#include "esif_participant.h"
#include "esif_pm.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified against Windows SDK/DDK included headers which we
* have no control over.
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
/* Debug Logging Defintions */
#define INIT_DEBUG 0
#define DSP_DEBUG 1
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_DSP, INIT_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_DSP(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_DSP, DSP_DEBUG, format, ##__VA_ARGS__)
/*
*****************************************************************************
* PRIVATE
*****************************************************************************
*/
/* Insert Primitive Into Hash */
static enum esif_rc insert_primitive(
const struct esif_lp_dsp *dsp_ptr,
struct esif_cpc_primitive *primitive_ptr
)
{
if (NULL == primitive_ptr)
return ESIF_E_PARAMETER_IS_NULL;
return esif_hash_table_put_item((u8 *)&primitive_ptr->tuple,/* Key */
sizeof(struct esif_primitive_tuple),
primitive_ptr,
dsp_ptr->ht_ptr);
}
/* Inspect Tuple */
static int is_same_primitive(
const struct esif_primitive_tuple *t1_ptr,
const struct esif_primitive_tuple *t2_ptr
)
{
if (NULL == t1_ptr || NULL == t2_ptr)
return 0;
ESIF_TRACE_DYN_DSP("%s: tuple 1 %d.%d.%d tuple 2 %d.%d.%d\n",
ESIF_FUNC,
t1_ptr->id, t1_ptr->domain, t1_ptr->instance,
t2_ptr->id, t2_ptr->domain, t2_ptr->instance);
return memcmp(t1_ptr, t2_ptr, sizeof(struct esif_primitive_tuple)) == 0;
}
/* Find Primitive In List */
static struct esif_cpc_primitive *find_primitive_in_list(
struct esif_link_list *list_ptr,
const struct esif_primitive_tuple *tuple_ptr
)
{
struct esif_cpc_primitive *cur_primitive_ptr = NULL;
struct esif_cpc_primitive *primitive_ptr = NULL;
struct esif_link_list_node *curr_ptr = list_ptr->head_ptr;
ESIF_TRACE_DYN_DSP("%s: number of linked list nodes %d\n",
ESIF_FUNC,
list_ptr->nodes);
while (curr_ptr) {
cur_primitive_ptr = (struct esif_cpc_primitive *)
curr_ptr->data_ptr;
if (cur_primitive_ptr != NULL) {
if (is_same_primitive(tuple_ptr,
&cur_primitive_ptr->tuple)) {
primitive_ptr = cur_primitive_ptr;
goto end;
}
}
curr_ptr = curr_ptr->next_ptr;
}
end:
return primitive_ptr;
}
/* Get Primitive */
static struct esif_lp_primitive *get_primitive(
const struct esif_lp_dsp *dsp_ptr,
const struct esif_primitive_tuple *tuple_ptr
)
{
struct esif_cpc_primitive *cpc_primitive_ptr = NULL;
struct esif_lp_primitive *primitive_ptr = NULL;
struct esif_link_list *row_ptr =
esif_hash_table_get_item(
(u8 *)tuple_ptr,
sizeof(struct esif_primitive_tuple),
dsp_ptr->ht_ptr);
if (NULL == row_ptr)
return NULL;
ESIF_TRACE_DYN_DSP("%s: tuple %d.%d.%d row %p\n",
ESIF_FUNC,
tuple_ptr->id,
tuple_ptr->domain,
tuple_ptr->instance,
row_ptr);
cpc_primitive_ptr = find_primitive_in_list(row_ptr, tuple_ptr);
if (NULL == cpc_primitive_ptr)
return NULL;
ESIF_TRACE_DYN_DSP("%s: have cpc primtive %p\n",
ESIF_FUNC,
cpc_primitive_ptr);
/*
* Okay now we have a CPC primitive pointer convert to standard ESIF
* primitive pointer and return. Note we can optimize this for these to
* be the same in the future.
*/
ESIF_TRACE_DYN_DSP(
"%s: have cpc primtive convert to esif primtive %p\n",
ESIF_FUNC,
cpc_primitive_ptr);
primitive_ptr = (struct esif_lp_primitive *)
esif_ccb_malloc(sizeof(*primitive_ptr));
if (NULL == primitive_ptr)
return NULL;
esif_ccb_memcpy((void *)&primitive_ptr->tuple,
&cpc_primitive_ptr->tuple,
sizeof(struct esif_primitive_tuple));
primitive_ptr->opcode = (enum esif_primitive_opcode)
cpc_primitive_ptr->operation;
primitive_ptr->action_count = (u8)cpc_primitive_ptr->number_of_actions;
return primitive_ptr;
}
/* Insert Algorithm Into Link List */
static enum esif_rc insert_algorithm(
const struct esif_lp_dsp *dsp_ptr,
struct esif_cpc_algorithm *algo_ptr
)
{
if (NULL == algo_ptr)
return ESIF_E_PARAMETER_IS_NULL;
esif_link_list_node_add(dsp_ptr->algo_ptr,
esif_link_list_create_node((void *)algo_ptr));
return ESIF_OK;
}
/* Get Algorithm Of An Action From Linked List */
struct esif_cpc_algorithm *get_algorithm(
const struct esif_lp_dsp *dsp_ptr,
const enum esif_action_type action_type
)
{
struct esif_link_list *list_ptr = dsp_ptr->algo_ptr;
struct esif_link_list_node *curr_ptr = list_ptr->head_ptr;
struct esif_cpc_algorithm *curr_algo_ptr = NULL;
while (curr_ptr) {
curr_algo_ptr = (struct esif_cpc_algorithm *)curr_ptr->data_ptr;
if (curr_algo_ptr != NULL) {
if (curr_algo_ptr->action_type == action_type)
return curr_algo_ptr;
}
curr_ptr = curr_ptr->next_ptr;
}
return NULL;
}
/* Has This Algorithm In DSP From Linked List Or Not */
static u32 dsp_has_algorithm(
const struct esif_lp_dsp *dsp_ptr,
const enum esif_algorithm_type algo)
{
struct esif_link_list *list_ptr = dsp_ptr->algo_ptr;
struct esif_link_list_node *curr_ptr = list_ptr->head_ptr;
struct esif_cpc_algorithm *curr_algo_ptr = NULL;
while (curr_ptr) {
curr_algo_ptr = (struct esif_cpc_algorithm *)curr_ptr->data_ptr;
if (curr_algo_ptr != NULL) {
if ((enum esif_algorithm_type) curr_algo_ptr->temp_xform == algo ||
(enum esif_algorithm_type) curr_algo_ptr->power_xform == algo ||
(enum esif_algorithm_type) curr_algo_ptr->time_xform == algo )
return ESIF_TRUE;
}
curr_ptr = curr_ptr->next_ptr;
}
return ESIF_FALSE;
}
/* Insert Events Into Link List */
static enum esif_rc insert_event(
const struct esif_lp_dsp *dsp_ptr,
struct esif_cpc_event *evt_ptr
)
{
if (NULL == evt_ptr)
return ESIF_E_PARAMETER_IS_NULL;
esif_link_list_node_add(dsp_ptr->evt_ptr,
esif_link_list_create_node((void *)evt_ptr));
return ESIF_OK;
}
/* Get Event From Linked List */
struct esif_cpc_event *get_event(
const struct esif_lp_dsp *dsp_ptr,
u32 notify_id
)
{
struct esif_link_list *list_ptr = dsp_ptr->evt_ptr;
struct esif_link_list_node *curr_ptr = list_ptr->head_ptr;
struct esif_cpc_event *curr_evt_ptr = NULL;
while (curr_ptr) {
curr_evt_ptr = (struct esif_cpc_event *)curr_ptr->data_ptr;
if (curr_evt_ptr != NULL) {
if ((u8)curr_evt_ptr->event_key[0] == notify_id)
return curr_evt_ptr;
}
curr_ptr = curr_ptr->next_ptr;
}
return NULL;
}
/* DSP Interface */
static esif_string get_code(const struct esif_lp_dsp *dsp_ptr)
{
if (dsp_ptr->code_ptr)
return dsp_ptr->code_ptr;
else
return ESIF_NOT_AVAILABLE;
}
static u8 get_domain_count(const struct esif_lp_dsp *dsp_ptr)
{
if (dsp_ptr->domain_count_ptr)
return *dsp_ptr->domain_count_ptr;
else
return 0;
}
static u8 get_ver_major(const struct esif_lp_dsp *dsp_ptr)
{
if (dsp_ptr->ver_major_ptr)
return *dsp_ptr->ver_major_ptr;
else
return 0;
}
static u8 get_ver_minor(const struct esif_lp_dsp *dsp_ptr)
{
if (dsp_ptr->ver_minor_ptr)
return *dsp_ptr->ver_minor_ptr;
else
return 0;
}
/* DSP Domain Interface */
static enum esif_domain_type get_domain_type(
const struct esif_lp_dsp *dsp_ptr,
u8 domain_index
)
{
if (dsp_ptr->domains_ptr)
return (dsp_ptr->domains_ptr + domain_index)->descriptor.domainType;
else
return 0x0;
}
static esif_flags_t get_domain_capability(
const struct esif_lp_dsp *dsp_ptr,
u8 domain_index
)
{
if (dsp_ptr->domains_ptr)
return (dsp_ptr->domains_ptr +
domain_index)->capability_for_domain.capability_flags;
else
return 0x0;
}
static u16 get_domain_id(
const struct esif_lp_dsp *dsp_ptr,
u8 domain_index
)
{
if (dsp_ptr->domains_ptr) {
return (dsp_ptr->domains_ptr +
domain_index)->descriptor.qualifier;
} else {
return 0x0;
}
}
static esif_string get_domain_desc(
const struct esif_lp_dsp *dsp_ptr,
u8 domain_index
)
{
if (dsp_ptr->domains_ptr)
return (dsp_ptr->domains_ptr + domain_index)->descriptor.description;
else
return ESIF_NOT_AVAILABLE;
}
static esif_string get_domain_name(
const struct esif_lp_dsp *dsp_ptr,
u8 domain_index
)
{
if (dsp_ptr->domains_ptr)
return (dsp_ptr->domains_ptr + domain_index)->descriptor.name;
else
return ESIF_NOT_AVAILABLE;
}
static enum esif_action_type get_type(const struct esif_lp_action *action_ptr)
{
return action_ptr->type;
}
static u32 get_p1_u32(const struct esif_lp_action *action_ptr)
{
if (action_ptr->p1_ptr)
return *action_ptr->p1_ptr;
else
return 0;
}
static u32 get_p2_u32(const struct esif_lp_action *action_ptr)
{
if (action_ptr->p2_ptr)
return *action_ptr->p2_ptr;
else
return 0;
}
static u32 get_p3_u32(const struct esif_lp_action *action_ptr)
{
if (action_ptr->p3_ptr)
return *action_ptr->p3_ptr;
else
return 0;
}
static u32 get_p4_u32(const struct esif_lp_action *action_ptr)
{
if (action_ptr->p4_ptr)
return *action_ptr->p4_ptr;
else
return 0;
}
static u32 get_p5_u32(const struct esif_lp_action *action_ptr)
{
if (action_ptr->p5_ptr)
return *action_ptr->p5_ptr;
else
return 0;
}
/* Temp Constant 1 */
static u32 get_temp_c1(
const struct esif_lp_dsp *dsp_ptr,
const enum esif_action_type action
)
{
struct esif_cpc_algorithm *algo_ptr = NULL;
algo_ptr = dsp_ptr->get_algorithm(dsp_ptr, action);
if (NULL != algo_ptr)
return algo_ptr->tempC1;
else
return 0xffffffff;
}
/* Temp Constant 2 */
static u32 get_temp_c2(
const struct esif_lp_dsp *dsp_ptr,
const enum esif_action_type action
)
{
/* TODO: Assume tempC2 Is Slope */
struct esif_cpc_algorithm *algo_ptr = NULL;
algo_ptr = dsp_ptr->get_algorithm(dsp_ptr, action);
if (NULL != algo_ptr)
return algo_ptr->tempC2;
else
return 0xffffffff;
}
/* Get Action Will Change For CPC */
static struct esif_lp_action *get_action(
const struct esif_lp_dsp *dsp_ptr,
struct esif_lp_primitive *primitive_ptr,
u8 index
)
{
struct esif_cpc_primitive *cpc_primitive_ptr = NULL;
struct esif_cpc_action *cpc_action_ptr = NULL;
struct esif_lp_action *action_ptr = NULL;
struct esif_link_list *row_ptr = NULL;
if (NULL == dsp_ptr || NULL == primitive_ptr)
return NULL;
ESIF_TRACE_DYN_DSP("%s: dsp %p primitive %p index %d\n",
ESIF_FUNC, dsp_ptr, primitive_ptr, index);
/*
* Find The Original CPC Primtive it contains our actions layed out
* below it
*/
row_ptr = esif_hash_table_get_item((u8 *)&primitive_ptr->tuple,
sizeof(struct esif_primitive_tuple),
dsp_ptr->ht_ptr);
if (NULL == row_ptr)
return NULL;
ESIF_TRACE_DYN_DSP("%s: tuple %d.%d.%d row %p\n",
ESIF_FUNC,
primitive_ptr->tuple.id,
primitive_ptr->tuple.domain,
primitive_ptr->tuple.instance,
row_ptr);
cpc_primitive_ptr = find_primitive_in_list(row_ptr,
&primitive_ptr->tuple);
if (NULL == cpc_primitive_ptr)
return NULL;
ESIF_TRACE_DYN_DSP("%s: have cpc primtive %p\n",
ESIF_FUNC,
cpc_primitive_ptr);
cpc_action_ptr = (struct esif_cpc_action *)
((u8 *)cpc_primitive_ptr + sizeof(struct esif_cpc_primitive));
cpc_action_ptr += index;
ESIF_TRACE_DYN_DSP(
"%s: type %d num_valid_param %d param_valid %x:%x:%x:%x:%x p1 0x%08x p2 0x%08x p3 0x%08x p4 0x%08x p5 %08x\n",
ESIF_FUNC,
cpc_action_ptr->type,
(u32)cpc_action_ptr->num_valid_params,
(u32)cpc_action_ptr->param_valid[0],
(u32)cpc_action_ptr->param_valid[1],
(u32)cpc_action_ptr->param_valid[2],
(u32)cpc_action_ptr->param_valid[3],
(u32)cpc_action_ptr->param_valid[4],
cpc_action_ptr->param[0],
cpc_action_ptr->param[1],
cpc_action_ptr->param[2],
cpc_action_ptr->param[3],
cpc_action_ptr->param[4]);
/* Now Convert from a CPC to an ESIF Action */
action_ptr = (struct esif_lp_action *)esif_ccb_malloc(
sizeof(*action_ptr));
if (NULL == action_ptr)
return NULL;
action_ptr->type = (enum esif_action_type)cpc_action_ptr->type;
action_ptr->p1_ptr = &cpc_action_ptr->param[0];
action_ptr->p2_ptr = &cpc_action_ptr->param[1];
action_ptr->p3_ptr = &cpc_action_ptr->param[2];
action_ptr->p4_ptr = &cpc_action_ptr->param[3];
action_ptr->p5_ptr = &cpc_action_ptr->param[4];
action_ptr->get_type = get_type;
action_ptr->get_p1_u32 = get_p1_u32;
action_ptr->get_p2_u32 = get_p2_u32;
action_ptr->get_p3_u32 = get_p3_u32;
action_ptr->get_p4_u32 = get_p4_u32;
action_ptr->get_p5_u32 = get_p5_u32;
ESIF_TRACE_DYN_DSP("%s: HAVE Action %d p1 %p p2 %p p3 %p p4 %p p5 %p\n",
ESIF_FUNC,
get_type(action_ptr),
action_ptr->p1_ptr,
action_ptr->p2_ptr,
action_ptr->p3_ptr,
action_ptr->p4_ptr,
action_ptr->p5_ptr);
return action_ptr;
}
/* Allocate DSP */
static struct esif_lp_dsp *esif_dsp_alloc(void)
{
struct esif_lp_dsp *dsp_ptr = NULL;
dsp_ptr = (struct esif_lp_dsp *)
esif_ccb_mempool_zalloc(ESIF_MEMPOOL_TYPE_DSP);
if (NULL == dsp_ptr)
return NULL;
/* Assign Function Pointers */
dsp_ptr->get_code = get_code;
dsp_ptr->get_ver_minor = get_ver_minor;
dsp_ptr->get_ver_major = get_ver_major;
dsp_ptr->get_temp_tc1 = get_temp_c1;
dsp_ptr->get_temp_tc2 = get_temp_c2;
dsp_ptr->get_domain_count = get_domain_count;
/* Domains */
dsp_ptr->get_domain_id = get_domain_id;
dsp_ptr->get_domain_capability = get_domain_capability;
dsp_ptr->get_domain_desc = get_domain_desc;
dsp_ptr->get_domain_name = get_domain_name;
dsp_ptr->get_domain_type = get_domain_type;
dsp_ptr->insert_primitive = insert_primitive;
dsp_ptr->insert_algorithm = insert_algorithm;
dsp_ptr->insert_event = insert_event;
dsp_ptr->get_primitive = get_primitive;
dsp_ptr->get_algorithm = get_algorithm;
dsp_ptr->dsp_has_algorithm = dsp_has_algorithm;
dsp_ptr->get_action = get_action;
dsp_ptr->get_event = get_event;
esif_ccb_lock_init(&dsp_ptr->lock);
return dsp_ptr;
}
/* Free DSP */
static void esif_dsp_free(struct esif_lp_dsp *dsp_ptr)
{
if (NULL == dsp_ptr)
return;
esif_ccb_lock_uninit(&dsp->lock);
esif_ccb_mempool_free(ESIF_MEMPOOL_TYPE_DSP, dsp_ptr);
}
/* Load */
enum esif_rc esif_dsp_load(
struct esif_lp *lp_ptr,
const struct esif_data *cpc_ptr
)
{
enum esif_rc rc = ESIF_OK;
u8 domain_index;
if (NULL == lp_ptr)
return ESIF_E_PARAMETER_IS_NULL;
ESIF_TRACE_DYN_DSP("%s: DSP Load(%s) CPC=%p, len=%d\n",
ESIF_FUNC,
lp_ptr->pi_ptr->name,
cpc_ptr->buf_ptr,
cpc_ptr->buf_len);
/* Allocate DSP */
lp_ptr->dsp_ptr = esif_dsp_alloc();
if (NULL == lp_ptr->dsp_ptr)
return ESIF_E_NO_MEMORY;
/* Allocate Hash Table */
lp_ptr->dsp_ptr->ht_ptr = esif_hash_table_create(31);
if (NULL == lp_ptr->dsp_ptr->ht_ptr)
return ESIF_E_NO_MEMORY;
/* Allocate Linked List */
lp_ptr->dsp_ptr->algo_ptr = esif_link_list_create();
if (NULL == lp_ptr->dsp_ptr->algo_ptr)
return ESIF_E_NO_MEMORY;
lp_ptr->dsp_ptr->evt_ptr = esif_link_list_create();
if (NULL == lp_ptr->dsp_ptr->evt_ptr)
return ESIF_E_NO_MEMORY;
/* Now Unpack Our CPC */
rc = esif_cpc_unpack(lp_ptr->dsp_ptr, cpc_ptr);
if (ESIF_OK == rc) {
/* Assign For Each Domain */
lp_ptr->domain_count = lp_ptr->dsp_ptr->get_domain_count(
lp_ptr->dsp_ptr);
/*
** Force one domain for DPTFZ
*/
if (lp_ptr->pi_ptr->flags & ESIF_FLAG_DPTFZ)
lp_ptr->domain_count = 1;
for (domain_index = 0; domain_index < lp_ptr->domain_count;
domain_index++) {
lp_ptr->domains[domain_index].instance = domain_index;
lp_ptr->domains[domain_index].lp_ptr = lp_ptr;
lp_ptr->domains[domain_index].id =
get_domain_id(lp_ptr->dsp_ptr, domain_index);
lp_ptr->domains[domain_index].name_ptr =
get_domain_name(lp_ptr->dsp_ptr, domain_index);
lp_ptr->domains[domain_index].desc_ptr =
get_domain_desc(lp_ptr->dsp_ptr, domain_index);
lp_ptr->domains[domain_index].capabilities =
get_domain_capability(lp_ptr->dsp_ptr,
domain_index);
lp_ptr->domains[domain_index].domainType =
get_domain_type(lp_ptr->dsp_ptr, domain_index);
ESIF_TRACE_DYN_DSP(
"%s: DOMAIN instance=%d, id=%d, name=%s, desc=%s, capabilities=%08x type=%d\n",
ESIF_FUNC,
domain_index,
lp_ptr->domains[domain_index].id,
lp_ptr->domains[domain_index].name_ptr,
lp_ptr->domains[domain_index].desc_ptr,
lp_ptr->domains[domain_index].capabilities,
lp_ptr->domains[domain_index].domainType);
}
/* Transistion State Instrument Domains */
esif_lf_pm_lp_set_state(lp_ptr,
ESIF_PM_PARTICIPANT_STATE_REGISTERED);
}
return rc;
}
/* Unload */
void esif_dsp_unload(struct esif_lp *lp_ptr)
{
if (NULL == lp_ptr || NULL == lp_ptr->dsp_ptr)
return;
ESIF_TRACE_DYN_DSP("%s: DSP UnLoad = %p\n", ESIF_FUNC, lp_ptr->dsp_ptr);
/* Transition State Unistrument Domains If Registered */
if (ESIF_PM_PARTICIPANT_STATE_REGISTERED ==
esif_lf_pm_lp_get_state(lp_ptr))
esif_lf_pm_lp_set_state(lp_ptr,
ESIF_PM_PARTICIPANT_STATE_NEEDDSP);
if (NULL != lp_ptr->dsp_ptr->algo_ptr)
esif_link_list_destroy(lp_ptr->dsp_ptr->algo_ptr);
if (NULL != lp_ptr->dsp_ptr->evt_ptr)
esif_link_list_destroy(lp_ptr->dsp_ptr->evt_ptr);
if (NULL != lp_ptr->dsp_ptr->ht_ptr)
esif_hash_table_destroy(lp_ptr->dsp_ptr->ht_ptr);
if (NULL != lp_ptr->dsp_ptr->cpc_ptr)
esif_cpc_free(lp_ptr->dsp_ptr);
if (NULL != lp_ptr->dsp_ptr->table) {
esif_ccb_free(lp_ptr->dsp_ptr->table);
lp_ptr->dsp_ptr->table = NULL;
lp_ptr->dsp_ptr->table_size = 0;
}
esif_dsp_free(lp_ptr->dsp_ptr);
lp_ptr->dsp_ptr = NULL;
}
/* Init */
enum esif_rc esif_dsp_init(void)
{
struct esif_ccb_mempool *mempool_ptr = NULL;
ESIF_TRACE_DYN_INIT("%s: Initialize DSP Engine\n", ESIF_FUNC);
mempool_ptr = esif_ccb_mempool_create(ESIF_MEMPOOL_TYPE_DSP,
ESIF_MEMPOOL_FW_DSP,
sizeof(struct esif_lp_dsp));
if (NULL == mempool_ptr)
return ESIF_E_NO_MEMORY;
esif_cpc_init();
return ESIF_OK;
}
/* Exit */
void esif_dsp_exit(void)
{
esif_cpc_exit();
ESIF_TRACE_DYN_INIT("%s: Exit DSP Engine\n", ESIF_FUNC);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,552 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_lf.h"
#include "esif_event.h"
#include "esif_queue.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified against Windows SDK/DDK included headers which we
* have no control over.
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
#define INIT_DEBUG 0
#define EVENT_DEBUG 1
#define DECODE_DEBUG 2
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_EVENT, INIT_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_EVENT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_EVENT, EVENT_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_DECODE(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_EVENT, DECODE_DEBUG, format, ##__VA_ARGS__)
/* Event Lock */
static esif_ccb_lock_t g_event_lock;
/* Transaction ID each event will have a unique ID */
static u64 g_event_transaction_id; /* No need to set 0 */
/* Queue */
struct esif_queue_instance *g_event_queue; /* No need to set NULL */;
static char *g_event_queue_name = "EVENT";
static enum esif_rc esif_lf_allocate_and_queue_event(
struct esif_lp *lp_ptr,
enum esif_event_type type,
struct esif_event **event_locPtr
);
enum esif_rc esif_lf_event(
struct esif_participant_iface *pi_ptr,
enum esif_event_type type,
u16 domain,
struct esif_data *data_ptr
)
{
enum esif_rc rc = ESIF_OK;
struct esif_lp *lp_ptr = NULL;
struct esif_event *event_ptr = NULL;
struct esif_ipc *ipc_ptr = NULL;
struct esif_cpc_event *cpc_event_ptr = NULL;
u16 ipc_data_len = 0;
struct esif_ipc_event_header evt_hdr = {0};
struct esif_ipc_event_data_create_participant evt_data = {0};
lp_ptr = esif_lf_pm_lp_get_by_pi(pi_ptr);
if (NULL == lp_ptr) {
rc = ESIF_E_PARTICIPANT_NOT_FOUND;
goto exit;
}
/* Create An Event */
switch (type) {
/* Special Event Create Send Entire PI Information */
case ESIF_EVENT_PARTICIPANT_CREATE:
{
event_ptr = esif_event_allocate(ESIF_EVENT_PARTICIPANT_CREATE,
sizeof(evt_data),
ESIF_EVENT_PRIORITY_NORMAL,
lp_ptr->instance,
ESIF_INSTANCE_UF,
domain,
pi_ptr);
if (NULL == event_ptr) {
rc = ESIF_E_NO_MEMORY;
goto exit;
}
ipc_data_len = sizeof(struct esif_ipc_event_header) +
sizeof(struct esif_ipc_event_data_create_participant);
ipc_ptr = esif_ipc_alloc(ESIF_IPC_TYPE_EVENT, ipc_data_len);
if (NULL == ipc_ptr) {
rc = ESIF_E_NO_MEMORY;
esif_event_free(event_ptr);
goto exit;
}
/* Setup Event Header And Copy To IPC Buffer */
evt_hdr.version = event_ptr->version;
evt_hdr.type = event_ptr->type;
evt_hdr.id = event_ptr->id;
evt_hdr.timestamp = event_ptr->timestamp;
evt_hdr.priority = event_ptr->priority;
evt_hdr.src_id = event_ptr->src;
evt_hdr.dst_id = event_ptr->dst;
evt_hdr.dst_domain_id = 'NA'; /* event_ptr->dst_domain_id; */
evt_hdr.data_len =
sizeof(struct esif_ipc_event_data_create_participant);
esif_ccb_memcpy(ipc_ptr + 1,
&evt_hdr,
sizeof(struct esif_ipc_event_header));
/* Setup Event Data Structure */
evt_data.id = lp_ptr->instance;
evt_data.version = lp_ptr->pi_ptr->version;
evt_data.enumerator = lp_ptr->pi_ptr->enumerator;
evt_data.flags = lp_ptr->pi_ptr->flags;
evt_data.pci_vendor = lp_ptr->pi_ptr->pci_vendor;
evt_data.pci_device = lp_ptr->pi_ptr->pci_device;
evt_data.pci_bus = lp_ptr->pi_ptr->pci_bus;
evt_data.pci_bus_device = lp_ptr->pi_ptr->pci_bus_device;
evt_data.pci_function = lp_ptr->pi_ptr->pci_function;
evt_data.pci_revision = lp_ptr->pi_ptr->pci_revision;
evt_data.pci_class = lp_ptr->pi_ptr->pci_class;
evt_data.pci_sub_class = lp_ptr->pi_ptr->pci_sub_class;
evt_data.pci_prog_if = lp_ptr->pi_ptr->pci_prog_if;
/*
** Handle these slow but safe.
*/
esif_ccb_memcpy(&evt_data.class_guid,
lp_ptr->pi_ptr->class_guid,
ESIF_GUID_LEN);
esif_ccb_memcpy(&evt_data.name,
lp_ptr->pi_ptr->name,
ESIF_NAME_LEN);
esif_ccb_memcpy(&evt_data.desc,
lp_ptr->pi_ptr->desc,
ESIF_DESC_LEN);
esif_ccb_memcpy(&evt_data.driver_name,
lp_ptr->pi_ptr->driver_name,
ESIF_NAME_LEN);
esif_ccb_memcpy(&evt_data.device_name,
lp_ptr->pi_ptr->device_name,
ESIF_NAME_LEN);
esif_ccb_memcpy(&evt_data.device_path,
lp_ptr->pi_ptr->device_path,
ESIF_PATH_LEN);
esif_ccb_memcpy(&evt_data.acpi_device,
lp_ptr->pi_ptr->acpi_device,
ESIF_SCOPE_LEN);
esif_ccb_memcpy(&evt_data.acpi_scope,
lp_ptr->pi_ptr->acpi_scope,
ESIF_SCOPE_LEN);
esif_ccb_memcpy(&evt_data.acpi_uid,
lp_ptr->pi_ptr->acpi_uid,
sizeof(evt_data.acpi_uid));
evt_data.acpi_type = lp_ptr->pi_ptr->acpi_type;
esif_ccb_memcpy(((u8 *)(ipc_ptr + 1) +
sizeof(struct esif_ipc_event_header)),
&evt_data,
sizeof(evt_data));
/* IPC will be freed on othre side of queue operation */
esif_event_queue_push(ipc_ptr);
break;
}
/* ACPI Events are special the incoming data will contain the OS notify
* type.
* We will map
* that to an ESIF DSP event with the aide of the DSP.
*/
case ESIF_EVENT_ACPI:
{
u32 acpi_notify = 0;
/* Map ACPI into ESIF event number (if DSP is loaded) in
*interrupt context */
if ((NULL != lp_ptr) &&
(NULL != lp_ptr->dsp_ptr) &&
(NULL != data_ptr)) {
/* Be paranoid make sue this is truly our EVENT data */
if (data_ptr->buf_len == sizeof(u32) &&
data_ptr->data_len == sizeof(u32) &&
ESIF_DATA_UINT32 == data_ptr->type) {
acpi_notify = *(u32 *)data_ptr->buf_ptr;
}
cpc_event_ptr = lp_ptr->dsp_ptr->get_event(
lp_ptr->dsp_ptr,
acpi_notify);
if (NULL != cpc_event_ptr) {
/* Translate ESIF_EVENT_ACPI->real ESIF event */
type = cpc_event_ptr->esif_event;
ESIF_TRACE_DYN_EVENT(
"%s: Mapped ACPI event 0x%08x to "
"ESIF Event %s(%d)\n",
ESIF_FUNC,
acpi_notify,
esif_event_type_str(type),
type);
} else {
ESIF_TRACE_DYN_EVENT(
"%s: Undefined ACPI event 0x%08x in "
"DSP! Cannot map to ESIF event!\n",
ESIF_FUNC,
acpi_notify);
rc = ESIF_E_UNSPECIFIED;
goto exit;
}
} else {
ESIF_TRACE_DYN_EVENT(
"%s: lp_ptr %p dsp_ptr %p data_ptr %p, none "
"cannot be null\n",
ESIF_FUNC,
lp_ptr,
lp_ptr->dsp_ptr,
data_ptr);
rc = ESIF_E_UNSPECIFIED;
goto exit;
}
rc = esif_lf_allocate_and_queue_event(lp_ptr, type, &event_ptr);
if (rc != ESIF_OK)
goto exit;
break;
}
case ESIF_EVENT_PARTICIPANT_SUSPEND:
{
if (ESIF_PM_PARTICIPANT_STATE_REGISTERED ==
esif_lf_pm_lp_get_state(lp_ptr))
esif_lf_pm_lp_set_state(lp_ptr,
ESIF_PM_PARTICIPANT_STATE_SUSPENDED);
rc = esif_lf_allocate_and_queue_event(lp_ptr, type, &event_ptr);
if(rc != ESIF_OK)
goto exit;
break;
}
case ESIF_EVENT_PARTICIPANT_RESUME:
{
if (ESIF_PM_PARTICIPANT_STATE_SUSPENDED ==
esif_lf_pm_lp_get_state(lp_ptr))
esif_lf_pm_lp_set_state(lp_ptr,
ESIF_PM_PARTICIPANT_STATE_RESUMED);
rc = esif_lf_allocate_and_queue_event(lp_ptr, type, &event_ptr);
if(rc != ESIF_OK)
goto exit;
break;
}
/* Everything Else Just Send The Handle */
default:
{
rc = esif_lf_allocate_and_queue_event(lp_ptr, type, &event_ptr);
if(rc != ESIF_OK)
goto exit;
break;
}
} /* End of case */
/* Send Our Event */
ESIF_TRACE_DYN_EVENT("type %s(%d)\n", esif_event_type_str(type), type);
esif_lf_send_all_events_in_queue_to_uf_by_ipc();
esif_lf_send_event(lp_ptr->pi_ptr, event_ptr);
esif_event_free(event_ptr);
exit:
return rc;
}
static enum esif_rc esif_lf_allocate_and_queue_event(
struct esif_lp *lp_ptr,
enum esif_event_type type,
struct esif_event **event_locPtr
)
{
enum esif_rc rc = ESIF_OK;
struct esif_event *event_ptr = NULL;
struct esif_ipc *ipc_ptr = NULL;
u16 ipc_data_len = 0;
struct esif_ipc_event_header evt_hdr = {0};
if ((NULL == lp_ptr) || (NULL == event_locPtr)) {
rc = ESIF_E_UNSPECIFIED;
goto exit;
}
event_ptr = esif_event_allocate(type,
sizeof(lp_ptr->instance),
ESIF_EVENT_PRIORITY_NORMAL,
lp_ptr->instance,
ESIF_INSTANCE_UF,
'NA',
&lp_ptr->instance);
if (NULL == event_ptr) {
rc = ESIF_E_NO_MEMORY;
goto exit;
}
ipc_data_len = sizeof(struct esif_ipc_event_header);
ipc_ptr = esif_ipc_alloc(ESIF_IPC_TYPE_EVENT, ipc_data_len);
if (NULL == ipc_ptr) {
esif_event_free(event_ptr);
event_ptr = NULL;
rc = ESIF_E_NO_MEMORY;
goto exit;
}
/* Setup Event Header And Copy To IPC Buffer */
evt_hdr.version = event_ptr->version;
evt_hdr.type = event_ptr->type;
evt_hdr.id = event_ptr->id;
evt_hdr.timestamp = event_ptr->timestamp;
evt_hdr.priority = event_ptr->priority;
evt_hdr.src_id = event_ptr->src;
evt_hdr.dst_id = event_ptr->dst;
evt_hdr.dst_domain_id = 'NA'; /* event_ptr->dst_domain_id; */
evt_hdr.data_len = 0;
esif_ccb_memcpy(ipc_ptr + 1,
&evt_hdr,
sizeof(struct esif_ipc_event_header));
/* IPC will be freed on other side of queue operation */
esif_event_queue_push(ipc_ptr);
*event_locPtr = event_ptr;
exit:
return rc;
}
/* Check Queue */
u32 esif_event_queue_size(void)
{
if (NULL != g_event_queue)
return esif_queue_size(g_event_queue);
return 0;
}
/* Poll Event Queue */
struct esif_ipc *esif_event_queue_pull()
{
if (NULL != g_event_queue)
return esif_queue_pull(g_event_queue);
return NULL;
}
/* Push Event Queue */
enum esif_rc esif_event_queue_push(struct esif_ipc *ipc_ptr)
{
if (NULL == g_event_queue || NULL == ipc_ptr)
return ESIF_E_PARAMETER_IS_NULL;
return esif_queue_push(g_event_queue, ipc_ptr);
}
/* Put Event Back in Queue */
enum esif_rc esif_event_queue_requeue(struct esif_ipc *ipc_ptr)
{
if (NULL == g_event_queue || NULL == ipc_ptr)
return ESIF_E_PARAMETER_IS_NULL;
return esif_queue_requeue(g_event_queue, ipc_ptr);
}
/* Documented In Header */
struct esif_event *esif_event_allocate(
const enum esif_event_type type,
const u16 size,
const enum esif_event_priority priority,
const u8 src,
const u8 dst,
const u16 dst_domain_id,
const void *data_ptr
)
{
u16 new_size = size + sizeof(struct esif_event);
struct esif_event *event_ptr = NULL;
event_ptr = esif_ccb_memtype_zalloc(ESIF_MEMTYPE_TYPE_EVENT, new_size);
if (event_ptr) {
event_ptr->version = ESIF_EVENT_VERSION;
event_ptr->size = new_size;
event_ptr->type = type;
event_ptr->priority = priority;
event_ptr->src = src;
event_ptr->dst = dst;
event_ptr->dst_domain_id = dst_domain_id;
event_ptr->data_size = size;
/*
* Assign Function Pointers If Any
*/
#ifdef ESIF_EVENT_DEBUG
event_ptr->get_type_str = esif_event_type_str;
event_ptr->get_priority_str = esif_event_priority_str;
event_ptr->dump = esif_dump_event;
#endif
/*
** Transaction ID
*/
esif_ccb_write_lock(&g_event_lock);
event_ptr->id = g_event_transaction_id++;
esif_ccb_write_unlock(&g_event_lock);
/*
** Time Stamp
*/
esif_ccb_system_time(&event_ptr->timestamp);
/*
** Make A Copy Of The Data To Make Sure It Is Contigous
** In The Buffer
*/
if (NULL != data_ptr)
esif_ccb_memcpy((event_ptr + 1), data_ptr, size);
ESIF_TRACE_DYN_EVENT("%s: buf %p bytes %d\n",
ESIF_FUNC,
event_ptr,
new_size);
ESIF_TRACE_DYN_DECODE("Version: %d\n"
"Type: %s(%d)\n"
"ID: %llu\n"
"Timestamp: %llu\n"
"Priority: %s(%d)\n"
"Source: %d\n"
"Destination: %d\n"
"Data Size: %d\n",
event_ptr->version,
esif_event_type_str(event_ptr->type),
event_ptr->type,
event_ptr->id,
(u64)event_ptr->timestamp,
esif_event_priority_str(
event_ptr->priority),
event_ptr->priority,
event_ptr->src,
event_ptr->dst,
event_ptr->data_size);
}
return event_ptr;
}
/* Event Free */
void esif_event_free(const struct esif_event *event)
{
ESIF_TRACE_DYN_EVENT("%s: buf %p bytes %d\n",
ESIF_FUNC,
event,
event->size);
esif_ccb_memtype_free(ESIF_MEMTYPE_TYPE_EVENT, (void *)event);
}
/* Init */
enum esif_rc esif_event_init(void)
{
ESIF_TRACE_DYN_INIT("%s: Initialize Event\n", ESIF_FUNC);
g_event_queue = esif_queue_create(1024, g_event_queue_name);
if (NULL == g_event_queue)
return ESIF_E_NO_MEMORY;
esif_ccb_lock_init(&g_event_lock);
return ESIF_OK;
}
/* Exit */
void esif_event_exit(void)
{
esif_queue_destroy(g_event_queue);
esif_ccb_lock_uninit(&g_event_lock);
ESIF_TRACE_DYN_INIT("%s: Exit Event\n", ESIF_FUNC);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,663 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_pm.h"
#include "esif_lf.h"
#include "esif_lf_poll.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified against Windows SDK/DDK included headers which
* we have no control over.
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
#define INIT_DEBUG 0
#define PM_DEBUG 1
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_PMG, INIT_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_PM(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_PMG, PM_DEBUG, format, ##__VA_ARGS__)
/*
*******************************************************************************
** PRIVATE
*******************************************************************************
*/
/* Participant Manager Entry */
struct esif_pme {
enum esif_pm_participant_state state; /* Current Participant State */
struct esif_participant_iface *pi_ptr; /* Participant INTERFACE */
struct esif_lp *lp_ptr; /* Lower Participant Instance */
};
/* Package Manager */
struct esif_pm {
u8 pme_count; /* Current Reference Count */
struct esif_pme pme[MAX_PARTICIPANT_ENTRY]; /* Maximum Participants */
esif_ccb_lock_t lock; /* Package Manager Lock */
};
/*
** Package Manager. Keeps Track of all participant interfaces, lower
** participants and there corresponding state
*/
static struct esif_pm g_pm = {0};
/* Allocate Lower Participant Instance */
static struct esif_lp *esif_pm_lp_alloc(void)
{
struct esif_lp *lp_ptr = NULL;
lp_ptr = (struct esif_lp *)
esif_ccb_mempool_zalloc(ESIF_MEMPOOL_TYPE_PM);
return lp_ptr;
}
/* Free Lower Participant Instance */
static void esif_pm_lp_free(
struct esif_lp *lp_ptr
)
{
if (NULL == lp_ptr)
return;
esif_ccb_mempool_free(ESIF_MEMPOOL_TYPE_PM, lp_ptr);
}
/*
*******************************************************************************
** PUBLIC
*******************************************************************************
*/
/*
** Participant State Management
*/
/* Get Participant State */
enum esif_pm_participant_state esif_lf_pm_lp_get_state(
const struct esif_lp *lp_ptr
)
{
enum esif_pm_participant_state state;
state = ESIF_PM_PARTICIPANT_STATE_AVAILABLE;
if (lp_ptr->instance < MAX_PARTICIPANT_ENTRY) {
esif_ccb_read_lock(&g_pm.lock);
state = g_pm.pme[lp_ptr->instance].state;
esif_ccb_read_unlock(&g_pm.lock);
}
ESIF_TRACE_DYN_PM("%s: instance %d current state %s(%d)\n",
ESIF_FUNC,
lp_ptr->instance,
esif_pm_participant_state_str(state),
state);
return state;
}
static void esif_lf_pm_build_lpat(struct esif_lp *lp_ptr)
{
struct esif_lp_dsp *dsp_ptr = lp_ptr->dsp_ptr;
struct esif_primitive_tuple tuple_lpat = {
GET_TEMPERATURE_APPROX_TABLE, '0D', 255};
struct esif_data esif_lpat = {ESIF_DATA_BINARY, NULL, 0, 0};
struct esif_data esif_void = {ESIF_DATA_VOID, NULL, 0, 0};
enum esif_rc rc = ESIF_OK;
u32 size = sizeof(union esif_data_variant) * 1024; /* ie. 512 LPAT */
/* Allow Upto 512 LPAT Entries (Each Takes Two Integer In
* esif_data_variant{}, For Example, {{INT64, -20}, {UINT64, 997}}
* Represents An Entry {Temp=-20, RawValue=996} In LPAT ACPI Obj.)
*/
esif_lpat.buf_ptr = (void *)esif_ccb_malloc(size);
esif_lpat.buf_len = size;
if (NULL == esif_lpat.buf_ptr)
goto exit;
rc = esif_execute_primitive(lp_ptr, &tuple_lpat, &esif_void,
&esif_lpat, NULL);
if (ESIF_OK != rc) {
esif_ccb_free(esif_lpat.buf_ptr);
goto exit;
}
dsp_ptr->table = esif_lpat.buf_ptr;
dsp_ptr->table_size = esif_lpat.data_len;
exit:
return;
}
/* Set Participant State */
enum esif_rc esif_lf_pm_lp_set_state(
struct esif_lp *lp_ptr,
const enum esif_pm_participant_state state
)
{
struct esif_lp_dsp *dsp_ptr = NULL;
enum esif_rc rc = ESIF_OK;
u8 i = 0;
if (NULL == lp_ptr) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
ESIF_TRACE_DYN_PM("%s: instance %d new state %d\n",
ESIF_FUNC,
lp_ptr->instance,
state);
if (lp_ptr->instance >= MAX_PARTICIPANT_ENTRY) {
rc = ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS;
goto exit;
}
esif_ccb_write_lock(&g_pm.lock);
g_pm.pme[lp_ptr->instance].state = state;
esif_ccb_write_unlock(&g_pm.lock);
/* Have DSP Instrument If We Have DSP */
if (ESIF_PM_PARTICIPANT_STATE_REGISTERED == state) {
rc = esif_lf_instrument_participant(lp_ptr);
if (ESIF_OK != rc)
goto exit;
/* Build LPAT Before Others Can Use Its Xform */
dsp_ptr = lp_ptr->dsp_ptr;
if (NULL != dsp_ptr) {
if (dsp_ptr->dsp_has_algorithm(dsp_ptr,
ESIF_ALGORITHM_TYPE_TEMP_LPAT) == ESIF_TRUE)
esif_lf_pm_build_lpat(lp_ptr);
}
/* Have DSP Instrument Domain */
for (i = 0; i < lp_ptr->domain_count; i++) {
struct esif_lp_domain *lpd_ptr = &lp_ptr->domains[i];
/* Assign Hysteresis Here with Best Effort */
if (lpd_ptr->capabilities &
ESIF_CAPABILITY_TEMP_STATUS) {
struct esif_data esif_void =
{ESIF_DATA_VOID, NULL, 0, 0};
struct esif_data esif_hyst = {
ESIF_DATA_UINT32,
&lpd_ptr->temp_hysteresis,
sizeof(u32),
sizeof(u32)
};
struct esif_data esif_tjmax = {
ESIF_DATA_UINT32,
&lpd_ptr->temp_tjmax,
sizeof(u32),
sizeof(u32)
};
struct esif_primitive_tuple tuple_hyst = {
GET_TEMPERATURE_THRESHOLD_HYSTERESIS,
lpd_ptr->id,
255
};
struct esif_primitive_tuple tuple_tjmax = {
GET_PROC_TJMAX,
lpd_ptr->id,
255
};
/*
* Grab and intitialize lpd_ptr->temp_tjmax =
* GET_PROC_TJ_MAX. Don't use DSP constant tc1
* for this any longer use this value it will
* change from 100 to 90 to 105 depending on SKU
* get it from the hardware here.
*
* We need to get it as soon as possible there
* is a silicon bug that causes this value to be
* reported as 0x40 hex after a connected standy
* cycle for now we need to work around this by
* reading it early and hanging onto the value.
*
* TJMAX from the DSP is no longer needed. We
* will leave the two TC values for
* future use.
*/
esif_execute_primitive(lpd_ptr->lp_ptr,
&tuple_hyst,
&esif_void,
&esif_hyst,
NULL);
/* Get Unit Data Needed By Power Conversion */
esif_execute_primitive(lpd_ptr->lp_ptr,
&tuple_tjmax,
&esif_void,
&esif_tjmax,
NULL);
ESIF_TRACE_DYN_PM(
"%s: dmn %s hyst %d tjmax %d\n",
ESIF_FUNC,
lpd_ptr->name_ptr,
lpd_ptr->temp_hysteresis,
lpd_ptr->temp_tjmax);
lpd_ptr->temp_aux0 = ESIF_DOMAIN_TEMP_INVALID;
lpd_ptr->temp_aux1 = ESIF_DOMAIN_TEMP_INVALID;
}
esif_lf_instrument_capability(lpd_ptr);
if (lpd_ptr->capabilities &
ESIF_CAPABILITY_POWER_STATUS) {
struct esif_data esif_void =
{ESIF_DATA_VOID, NULL, 0, 0};
struct esif_data esif_energy = {
ESIF_DATA_UINT32,
&lpd_ptr->unit_energy,
sizeof(u32),
sizeof(u32)
};
struct esif_data esif_power = {
ESIF_DATA_UINT32,
&lpd_ptr->unit_power,
sizeof(u32),
sizeof(u32)
};
struct esif_data esif_time = {
ESIF_DATA_UINT32,
&lpd_ptr->unit_time,
sizeof(u32), sizeof(u32)
};
struct esif_primitive_tuple tuple_energy = {
GET_RAPL_ENERGY_UNIT, lpd_ptr->id, 255
};
struct esif_primitive_tuple tuple_power = {
GET_RAPL_POWER_UNIT, lpd_ptr->id, 255
};
struct esif_primitive_tuple tuple_time = {
GET_RAPL_TIME_UNIT, lpd_ptr->id, 255
};
/* Get Unit Data Needed By Power Conversion
* lpd_ptr->unit_power = GET_RAPL_POWER_UNIT
* lpd_ptr->unit_energy = GET_RAPL_ENERGY_UNIT
* lpd_ptr->unit_time = GET_RAPL_TIME_UNIT
*/
esif_execute_primitive(lpd_ptr->lp_ptr,
&tuple_energy,
&esif_void,
&esif_energy,
NULL);
esif_execute_primitive(lpd_ptr->lp_ptr,
&tuple_power,
&esif_void,
&esif_power,
NULL);
esif_execute_primitive(lpd_ptr->lp_ptr,
&tuple_time,
&esif_void,
&esif_time,
NULL);
ESIF_TRACE_DYN_PM(
"%s: dmn %s id %d energy %d power %d "
"time %d\n",
ESIF_FUNC,
lpd_ptr->name_ptr,
lpd_ptr->id,
lpd_ptr->unit_energy,
lpd_ptr->unit_power,
lpd_ptr->unit_time);
lpd_ptr->power_aux0 = 0;
lpd_ptr->power_aux1 = 10000000; /* Something
*other than
*zero */
lpd_ptr->poll_mask |= ESIF_POLL_POWER;
esif_poll_start(lpd_ptr);
}
}
} else if (ESIF_PM_PARTICIPANT_STATE_NEEDDSP == state) {
/*
* Uninstrument domains that currently have a DSP
*/
for (i = 0; i < lp_ptr->domain_count; i++) {
struct esif_lp_domain *lpd_ptr = &lp_ptr->domains[i];
esif_poll_stop(lpd_ptr);
esif_lf_uninstrument_capability(lpd_ptr);
}
esif_lf_uninstrument_participant(lp_ptr);
} else if (ESIF_PM_PARTICIPANT_STATE_SUSPENDED == state) {
for (i = 0; i < lp_ptr->domain_count; i++) {
struct esif_lp_domain *lpd_ptr = &lp_ptr->domains[i];
esif_poll_stop(lpd_ptr);
}
} else if (ESIF_PM_PARTICIPANT_STATE_RESUMED == state) {
for (i = 0; i < lp_ptr->domain_count; i++) {
struct esif_lp_domain *lpd_ptr = &lp_ptr->domains[i];
if (lp_ptr->domains[i].poll_mask != 0)
esif_poll_start(lpd_ptr);
}
esif_ccb_write_lock(&g_pm.lock);
g_pm.pme[lp_ptr->instance].state = ESIF_PM_PARTICIPANT_STATE_REGISTERED;
esif_ccb_write_unlock(&g_pm.lock);
}
exit:
return rc;
}
/*
** Participant Lookups
*/
/* Get Lower Participant INTERFACE By Instance ID */
struct esif_participant_iface *esif_lf_pm_pi_get_by_instance_id(
const u8 instance
)
{
struct esif_participant_iface *pi_ptr = NULL;
ESIF_TRACE_DYN_PM("%s: instance %d\n", ESIF_FUNC, instance);
if (instance >= MAX_PARTICIPANT_ENTRY)
goto exit;
esif_ccb_read_lock(&g_pm.lock);
if (g_pm.pme[instance].state > ESIF_PM_PARTICIPANT_REMOVED)
pi_ptr = g_pm.pme[instance].pi_ptr;
esif_ccb_read_unlock(&g_pm.lock);
exit:
if (NULL == pi_ptr)
ESIF_TRACE_DYN_PM(
"%s: instance %d NOT found or OUT OF BOUNDS\n",
ESIF_FUNC,
instance);
return pi_ptr;
}
/* Get Lower Participant By Instance ID */
struct esif_lp *esif_lf_pm_lp_get_by_instance_id(
const u8 instance
)
{
struct esif_lp *lp_ptr = NULL;
ESIF_TRACE_DYN_PM("%s: instance %d\n", ESIF_FUNC, instance);
if (instance >= MAX_PARTICIPANT_ENTRY)
goto exit;
esif_ccb_read_lock(&g_pm.lock);
if (g_pm.pme[instance].state > ESIF_PM_PARTICIPANT_REMOVED)
lp_ptr = g_pm.pme[instance].lp_ptr;
esif_ccb_read_unlock(&g_pm.lock);
exit:
if (NULL == lp_ptr)
ESIF_TRACE_DYN_PM(
"%s: instance %d NOT found or OUT OF BOUNDS\n",
ESIF_FUNC,
instance);
return lp_ptr;
}
/* Get Lower Participant By Particiapnt Interface */
struct esif_lp *esif_lf_pm_lp_get_by_pi(
const struct esif_participant_iface *pi_ptr
)
{
u8 i = 0;
struct esif_lp *lp_ptr = NULL;
if (NULL == pi_ptr)
goto exit;
esif_ccb_read_lock(&g_pm.lock);
for (i = 0; i < MAX_PARTICIPANT_ENTRY; i++) {
if (g_pm.pme[i].pi_ptr == pi_ptr) {
/* Found */
if(g_pm.pme[i].state > ESIF_PM_PARTICIPANT_REMOVED)
lp_ptr = g_pm.pme[i].lp_ptr;
break;
}
}
esif_ccb_read_unlock(&g_pm.lock);
exit:
return lp_ptr; /* Not Found Will Be NULL */
}
/* Create Participant Instance */
struct esif_lp *esif_lf_pm_lp_create(
struct esif_participant_iface *pi_ptr
)
{
u8 i = 0;
struct esif_lp *lp_ptr = NULL;
/* Lock Package Manager */
esif_ccb_write_lock(&g_pm.lock);
if (NULL == pi_ptr)
goto exit;
ESIF_TRACE_DYN_PM("%s: pi %p\n", ESIF_FUNC, pi_ptr);
/*
* First check for a participant that was previously removed.
* If found, reset to initial state, update participant count, and then
* update the pi_ptr as that may have changed when the participant
* was reloaded.
*/
for (i = ESIF_INSTANCE_FIRST; i < MAX_PARTICIPANT_ENTRY; i++) {
if ((g_pm.pme[i].state != ESIF_PM_PARTICIPANT_STATE_AVAILABLE)
&& (!memcmp(g_pm.pme[i].lp_ptr->pi_name,
pi_ptr->name,
sizeof(pi_ptr->name)))) {
g_pm.pme[i].pi_ptr = pi_ptr;
g_pm.pme[i].state = ESIF_PM_PARTICIPANT_STATE_CREATED;
g_pm.pme_count++;
lp_ptr = g_pm.pme[i].lp_ptr;
lp_ptr->pi_ptr = pi_ptr;
ESIF_TRACE_DYN_PM("%s: lp %p\n", ESIF_FUNC, lp_ptr);
goto exit;
}
}
/* Find Available Slot In Package Manager Table */
if (pi_ptr->flags & ESIF_FLAG_DPTFZ) {
i = 0; /* Treat DPTFZ Special As ID 0 */
} else {
/*
* Simple Table Lookup For Now. Scan Table And Find First Empty
* Slot indicated by AVAILABLE state
*/
for (i = ESIF_INSTANCE_FIRST; i < MAX_PARTICIPANT_ENTRY; i++) {
if (ESIF_PM_PARTICIPANT_STATE_AVAILABLE ==
g_pm.pme[i].state) {
break;
}
}
}
/* If No Available Slots Return */
if (i >= MAX_PARTICIPANT_ENTRY)
goto exit;
lp_ptr = esif_pm_lp_alloc();
if (NULL == lp_ptr)
goto exit;
ESIF_TRACE_DYN_PM("%s: lp %p\n", ESIF_FUNC, lp_ptr);
/*
* Take Slot
*/
g_pm.pme[i].state = ESIF_PM_PARTICIPANT_STATE_CREATED;
g_pm.pme_count++;
/*
* Initialize Our New Lower Participant
*/
lp_ptr->instance = i; /* Our PME Instance */
lp_ptr->enable = ESIF_TRUE; /* Enable By Default */
lp_ptr->pi_ptr = pi_ptr; /* Keep The Original Interface Data */
/*
* We copy the name so it may be used later when a participant is
* removed to tell when it returns.
*/
esif_ccb_strcpy(lp_ptr->pi_name, pi_ptr->name, ESIF_NAME_LEN);
/* Assume One Domain */
lp_ptr->domain_count = 1;
ESIF_TRACE_DYN_PM("%s: Assigned Instance: %d of %d\n",
ESIF_FUNC, lp_ptr->instance, MAX_PARTICIPANT_ENTRY);
g_pm.pme[i].pi_ptr = pi_ptr;
g_pm.pme[i].lp_ptr = lp_ptr;
exit:
esif_ccb_write_unlock(&g_pm.lock);
return lp_ptr;
}
/* Disable Paticipant Instance */
void esif_lf_pm_lp_remove(
struct esif_lp *lp_ptr
)
{
if (NULL == lp_ptr)
return;
ESIF_TRACE_DYN_PM("%s: lp %p\n", ESIF_FUNC, lp_ptr);
esif_ccb_write_lock(&g_pm.lock);
g_pm.pme[lp_ptr->instance].state = ESIF_PM_PARTICIPANT_REMOVED;
g_pm.pme_count--;
lp_ptr->enable = ESIF_FALSE; /* Not used anywhere that I can see */
lp_ptr->pi_ptr = NULL; /* Keep The Original Interface Data */
g_pm.pme[lp_ptr->instance].pi_ptr = NULL;
/* Note we don't free PI since that is someone elses */
esif_ccb_write_unlock(&g_pm.lock);
}
/* Initialize Participant Manager */
enum esif_rc esif_lf_pm_init(void)
{
enum esif_rc rc = ESIF_OK;
struct esif_ccb_mempool *mempool_ptr = NULL;
ESIF_TRACE_DYN_INIT("%s: Initialize Participant Manager\n", ESIF_FUNC);
mempool_ptr =
esif_ccb_mempool_create(ESIF_MEMPOOL_TYPE_PM,
ESIF_MEMPOOL_FW_PM,
sizeof(struct esif_lp));
if (NULL == mempool_ptr) {
rc = ESIF_E_NO_MEMORY;
goto exit;
}
esif_ccb_lock_init(&g_pm.lock);
exit:
return rc;
}
/* Exit Participant Manager */
void esif_lf_pm_exit(void)
{
u8 i = 0;
esif_ccb_write_lock(&g_pm.lock);
for (i = 0; i < MAX_PARTICIPANT_ENTRY; i++) {
esif_pm_lp_free(g_pm.pme[i].lp_ptr);
g_pm.pme[i].lp_ptr = NULL;
g_pm.pme[i].pi_ptr = NULL;
g_pm.pme_count--;
g_pm.pme[i].state = ESIF_PM_PARTICIPANT_STATE_AVAILABLE;
}
esif_ccb_write_unlock(&g_pm.lock);
esif_ccb_lock_uninit(&g_pm_lock);
ESIF_TRACE_DYN_INIT("%s: Exit Participant Manager\n", ESIF_FUNC);
}
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,401 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_lf_poll.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified against Windows SDK/DDK included headers which
* we have no control over.
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
#define INIT_DEBUG 0
#define POLL_DEBUG 1
#define RAPL_DEBUG 2
#define ENERGY_DEBUG 3
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_POL, INIT_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_POLL(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_POL, POLL_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_RAPL(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_POL, RAPL_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_ENERGY(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_POL, ENERGY_DEBUG, format, ##__VA_ARGS__)
/* TODO: Fix This */
int g_background = 1000;/* 1 Seconds */
/* Poll For Power and Send Event If Threshold Crossed */
static enum esif_rc esif_poll_power(
struct esif_lp_domain *lpd_ptr
)
{
enum esif_rc rc = ESIF_OK;
u32 energy_units = 0;
u32 energy_units_used = 0;
struct esif_primitive_tuple tuple = {GET_RAPL_ENERGY, lpd_ptr->id, 255};
struct esif_data req_data = {ESIF_DATA_VOID, NULL, 0, 0};
struct esif_data rsp_data = {ESIF_DATA_UINT32, &energy_units,
sizeof(energy_units), 0};
rc = esif_execute_primitive(lpd_ptr->lp_ptr,
&tuple,
&req_data,
&rsp_data,
NULL);
if (ESIF_OK != rc)
goto exit;
ESIF_TRACE_DYN_ENERGY(
"GET_RAPL_ENERGY for %s energy_unit 0x%x rc %s(%d)\n",
lpd_ptr->name_ptr,
energy_units,
esif_rc_str(rc),
rc);
/* Save the current and last RAPL energy counters */
lpd_ptr->rapl_energy_units_last = lpd_ptr->rapl_energy_units_current;
lpd_ptr->rapl_energy_units_current = energy_units;
/* Check For Wrap? */
if (lpd_ptr->rapl_energy_units_last > energy_units) {
/* force I_AGAIN */
lpd_ptr->rapl_energy_units_last = 0;
} else {
energy_units_used = energy_units -
lpd_ptr->rapl_energy_units_last;
}
/* TODO: Use a timestamp to make this as acurate as possible */
/* should be within a few usecs so good enough for now */
lpd_ptr->rapl_energy_units_per_sec = energy_units_used /
(lpd_ptr->timer_period_msec / 1000);
ESIF_TRACE_DYN_ENERGY(
"id %s ENERGY units current %08X, last %08X, used %u, used/sec %d\n",
lpd_ptr->name_ptr,
lpd_ptr->rapl_energy_units_last,
lpd_ptr->rapl_energy_units_current,
energy_units_used,
lpd_ptr->rapl_energy_units_per_sec);
/* Take two samples to get the right rapl_power and send_event. */
if (lpd_ptr->rapl_energy_units_last == 0)
goto exit;
/*
* Now Calculate Power
*/
if (lpd_ptr->rapl_energy_units_per_sec > 0) {
u32 energy_joules = 0;/* default micro joules unit */
u32 power = 0; /* default power */
struct esif_lp_domain *lpd_d0_ptr = NULL; /* For Domain 0 */
/*
* Don't HAVE Action Type Assume MSR since all processors
* have this
*/
struct esif_cpc_algorithm *algo_ptr =
lpd_ptr->lp_ptr->dsp_ptr->get_algorithm(
lpd_ptr->lp_ptr->dsp_ptr,
ESIF_ACTION_MSR);
/* Power Unit Data Only Lives in Domain 0 (D0) */
lpd_d0_ptr = &lpd_ptr->lp_ptr->domains[0];
if (algo_ptr && ESIF_ALGORITHM_TYPE_POWER_UNIT_CORE ==
algo_ptr->power_xform) {
if (lpd_d0_ptr->unit_energy) {
energy_joules = 1000000 /
(1 << lpd_d0_ptr->unit_energy);
} else {
/* 1000000uj / (2 ^ 14) = 61uj */
energy_joules = 61;
}
}
if (algo_ptr && ESIF_ALGORITHM_TYPE_POWER_UNIT_ATOM ==
algo_ptr->power_xform) {
if (lpd_d0_ptr->unit_energy) {
energy_joules = (1 << lpd_d0_ptr->unit_energy);
} else {
/* 1uj * (2 ^ 5) = 32 uj */
energy_joules = 32;
}
}
power = (lpd_ptr->rapl_energy_units_per_sec *
energy_joules) / 1000; /* .001 of watt accuracy */
/* Normalized from DeciW */
esif_convert_power(ESIF_POWER_MILLIW,
NORMALIZE_POWER_UNIT_TYPE,
&power);
ESIF_TRACE_DYN_RAPL("POWER %d %s(%d)\n",
power,
esif_power_unit_desc(
NORMALIZE_POWER_UNIT_TYPE),
NORMALIZE_POWER_UNIT_TYPE);
lpd_ptr->rapl_power = power;
/*
* Now Check For Threshold
*/
ESIF_TRACE_DYN_RAPL(
"THRESHOLD_CHECK hyst = %d aux0 = %d "
"power = %d aux1 = %d units %s(%d)\n",
lpd_ptr->power_hysteresis,
lpd_ptr->power_aux0,
power,
lpd_ptr->power_aux1,
esif_power_unit_desc(
NORMALIZE_POWER_UNIT_TYPE),
NORMALIZE_POWER_UNIT_TYPE);
if (0 == lpd_ptr->power_aux0 && 0 == lpd_ptr->power_aux1) {
/* Do Nothing */
} else {
if (0 == lpd_ptr->power_aux0) {
if (power > lpd_ptr->power_aux1) {
lpd_ptr->lp_ptr->pi_ptr->send_event(
lpd_ptr->lp_ptr->pi_ptr,
ESIF_EVENT_DOMAIN_POWER_THRESHOLD_CROSSED,
lpd_ptr->id,
NULL);
} else if (power < lpd_ptr->power_aux0 ||
power > lpd_ptr->power_aux1) {
lpd_ptr->lp_ptr->pi_ptr->send_event(
lpd_ptr->lp_ptr->pi_ptr,
ESIF_EVENT_DOMAIN_POWER_THRESHOLD_CROSSED,
lpd_ptr->id,
NULL);
}
}
}
}
exit:
return rc;
}
/* Poll For Temperature and Send Event If Threshold Crossed */
static enum esif_rc esif_poll_temperature(
struct esif_lp_domain *lpd_ptr
)
{
enum esif_rc rc = ESIF_OK;
u32 temp = 0;
struct esif_primitive_tuple tuple = {GET_TEMPERATURE, lpd_ptr->id, 255};
struct esif_data req_data = {ESIF_DATA_VOID, NULL, 0, 0};
struct esif_data rsp_data = {ESIF_DATA_TEMPERATURE, &temp,
sizeof(temp), 0};
rc = esif_execute_primitive(lpd_ptr->lp_ptr,
&tuple,
&req_data,
&rsp_data,
NULL);
if (ESIF_OK != rc)
goto exit;
ESIF_TRACE_DYN_TEMP("TEMPERATURE %d %s(%d)\n",
temp,
esif_temperature_type_desc(NORMALIZE_TEMP_TYPE),
NORMALIZE_TEMP_TYPE);
ESIF_TRACE_DYN_TEMP(
"THRESHOLD_CHECK hyst = %d aux0 = %d temp = %d aux1 = %d units %s(%d)\n",
lpd_ptr->temp_hysteresis,
lpd_ptr->temp_aux0,
temp,
lpd_ptr->temp_aux1,
esif_temperature_type_desc(NORMALIZE_TEMP_TYPE),
NORMALIZE_TEMP_TYPE);
if (((lpd_ptr->temp_aux0 != ESIF_DOMAIN_TEMP_INVALID) &&
(temp < lpd_ptr->temp_aux0 - lpd_ptr->temp_hysteresis)) ||
((lpd_ptr->temp_aux1 != ESIF_DOMAIN_TEMP_INVALID) &&
(temp >= lpd_ptr->temp_aux1))) {
lpd_ptr->lp_ptr->pi_ptr->send_event(lpd_ptr->lp_ptr->pi_ptr,
ESIF_EVENT_DOMAIN_TEMP_THRESHOLD_CROSSED,
lpd_ptr->id,
NULL);
ESIF_TRACE_DYN_TEMP("ESIF_EVENT_TEMP_THRESHOLD_CROSSED sent\n");
}
exit:
return rc;
}
void esif_poll(
void *context_ptr
)
{
struct esif_lp_domain *lpd_ptr = (struct esif_lp_domain *)context_ptr;
if (NULL == lpd_ptr)
return;
ESIF_TRACE_DYN_POLL("Timer %s:%s\n",
lpd_ptr->lp_ptr->pi_name,
lpd_ptr->name_ptr);
/* No DSP No Work */
if (NULL != lpd_ptr->lp_ptr->dsp_ptr) {
/* Do Work By Capability In Prioritized Order */
if (lpd_ptr->poll_mask & ESIF_POLL_POWER)
esif_poll_power(lpd_ptr);
if (lpd_ptr->poll_mask & ESIF_POLL_TEMPERATURE)
esif_poll_temperature(lpd_ptr);
} else {
ESIF_TRACE_DYN_POLL("no DSP can't do work\n");
}
}
/* Start Poll */
void esif_poll_start(
struct esif_lp_domain *lpd_ptr
)
{
enum esif_rc rc = ESIF_OK;
if (ESIF_TRUE == lpd_ptr->poll || 0 == g_background)
return;
lpd_ptr->timer_period_msec = g_background;
rc = esif_ccb_timer_init(&lpd_ptr->timer);
if (ESIF_OK != rc)
goto exit;
rc = esif_ccb_timer_set_msec(&lpd_ptr->timer,
lpd_ptr->timer_period_msec,
ESIF_TRUE,
esif_poll,
lpd_ptr);
if (ESIF_OK != rc)
goto exit;
ESIF_TRACE_DYN_POLL("Timer started for %s period %d\n",
lpd_ptr->name_ptr, g_background);
lpd_ptr->poll = ESIF_TRUE;
exit:
return;
}
/* Start All Poll Domain For Participants Instance */
void esif_poll_start_all(
struct esif_lp *lp_ptr
)
{
u8 domain_index = 0;
for (domain_index = 0; domain_index < lp_ptr->domain_count;
domain_index++)
esif_poll_start(&lp_ptr->domains[domain_index]);
}
/* Stop Poll */
void esif_poll_stop(
struct esif_lp_domain *lpd_ptr
)
{
if (ESIF_FALSE == lpd_ptr->poll)
return;
esif_ccb_timer_kill(&lpd_ptr->timer);
ESIF_TRACE_DYN_POLL("Timer stopped for %s period %d\n",
lpd_ptr->name_ptr, g_background);
/* Reset Power History */
lpd_ptr->rapl_energy_units_last = 0;
lpd_ptr->rapl_energy_units_current = 0;
lpd_ptr->rapl_power = 0;
lpd_ptr->poll = ESIF_FALSE;
}
/* Initialize Poll Manager */
enum esif_rc esif_poll_init(void)
{
return ESIF_OK;
}
/* Exit Poll Manager */
void esif_poll_exit(void)
{
ESIF_TRACE_DYN_INIT("Exit Polling\n");
}
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,77 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_LF_POLL_H_
#define _ESIF_LF_POLL_H_
#include "esif.h"
#include "esif_participant.h"
#define ESIF_POLL_POWER 0x00000001/* Power */
#define ESIF_POLL_TEMPERATURE 0x00000002/* Temperature */
/* Poll */
void esif_poll_start(struct esif_lp_domain *lpd_ptr);
void esif_poll_start_all(struct esif_lp *lp_ptr);
void esif_poll(void *context_ptr);
void esif_poll_stop(struct esif_lp_domain *lpd_ptr);
/* Init / Exit */
enum esif_rc esif_poll_init(void);
void esif_poll_exit(void);
#endif /* _ESIF_LF_POLL_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,478 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_primitive.h"
#include "esif_lf_action.h"
#include "esif_ipc.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified against Windows SDK/DDK included headers which
* we have no control over.
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
/* Debug Logging Defintions */
#define INIT_DEBUG 0 /* Init Debug */
#define PRIMITIVE_DEBUG 1 /* Primitive Debug */
#define DECODE_DEBUG 2 /* Decode Debug */
#define PRIMITIVE_DEBUG_DSP 3 /* Debug DSP */
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_PRIMITIVE, INIT_DEBUG, \
format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_PRIM(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_PRIMITIVE, PRIMITIVE_DEBUG, \
format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_DECODE(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_PRIMITIVE, DECODE_DEBUG, \
format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_PRIM_DPF(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_PRIMITIVE, PRIMITIVE_DEBUG_DSP, \
format, ##__VA_ARGS__)
/*
******************************************************************************
* PRIVATE
******************************************************************************
*/
/* u16 To String */
static char *esif_primitive_domain_str(
u16 domain,
char *str_ptr
)
{
esif_ccb_memcpy(str_ptr, &domain, 2); /* Two Byte String */
*(str_ptr + 2) = 0; /* Null Terminate */
return str_ptr;
}
/* u32 To String */
static char *esif_action_acpi_str(
u32 method,
char *str_ptr
)
{
esif_ccb_memcpy(str_ptr, &method, 4); /* Four Byte String */
*(str_ptr + 4) = 0; /* Null Terminate */
return str_ptr;
}
/* Print Action */
static void esif_action_dump(struct esif_lp_action *action_ptr)
{
/* Done this way to fix compiler warning in release build */
char tmp[8];
tmp[0] = '\0';
/* First action that succeeds wins */
ESIF_TRACE_DYN_DECODE(
"ACTION TYPE P1 P2 "
"P3 P4 P5\n"
"----------------------------- ---------- ---------- "
"---------- ---------- ----------\n"
"%-25s(%02d) 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
esif_action_type_str(action_ptr->type),
action_ptr->type,
action_ptr->get_p1_u32(action_ptr),
action_ptr->get_p2_u32(action_ptr),
action_ptr->get_p3_u32(action_ptr),
action_ptr->get_p4_u32(action_ptr),
action_ptr->get_p5_u32(action_ptr));
if (ESIF_ACTION_ACPI == action_ptr->type) {
ESIF_TRACE_DYN_DECODE("ACPI Method: %s\n",
esif_action_acpi_str(action_ptr->get_p1_u32(action_ptr),
tmp));
} else if (ESIF_ACTION_KODE == action_ptr->type) {
ESIF_TRACE_DYN_DECODE("Code Method: %s\n",
esif_action_acpi_str(action_ptr->get_p1_u32(action_ptr),
tmp));
}
return;
}
static enum esif_rc esif_lf_primitive_get_and_execute_action(
struct esif_lp_primitive *primitive_ptr,
struct esif_lp *lp_ptr,
const struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr,
u8 action
)
{
enum esif_rc rc = ESIF_OK;
struct esif_lp_action *action_ptr = NULL;
if (NULL == lp_ptr) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
action_ptr = lp_ptr->dsp_ptr->get_action(lp_ptr->dsp_ptr,
primitive_ptr,
action);
if (NULL == action_ptr) {
rc = ESIF_E_PRIMITIVE_NOT_FOUND_IN_DSP;
goto exit;
}
esif_action_dump(action_ptr);
/* Have Action Now Execute */
rc = esif_execute_action(lp_ptr,
primitive_ptr,
action_ptr,
(struct esif_data *)req_data_ptr,
rsp_data_ptr);
ESIF_TRACE_DYN_PRIM("%s: PRIMITIVE ACTION(%d) return type: %s(%d)\n",
ESIF_FUNC, action, esif_rc_str(rc), rc);
exit:
if (action_ptr != NULL)
esif_ccb_free(action_ptr);
return rc;
}
/*
******************************************************************************
* PUBLIC
******************************************************************************
*/
/*
* Execute IPC Primitive
* Gets primitive data from IPC structure, looks up the participatn associated
* with the primitive, and then executes the primitive. After execution,
* sets the response data in the primitive for return to caller.
*/
struct esif_ipc *esif_execute_ipc_primitive(struct esif_ipc *ipc_ptr)
{
enum esif_rc rc = ESIF_OK;
struct esif_lp *lp_ptr = NULL;
struct esif_ipc_primitive *primitive_ptr =
(struct esif_ipc_primitive *)(ipc_ptr + 1);
u8 *data_ptr = (u8 *)primitive_ptr + sizeof(*primitive_ptr);
u32 data_size = 0;
struct esif_data req_data = {
primitive_ptr->req_data_type,
data_ptr + primitive_ptr->req_data_offset,
primitive_ptr->req_data_len,
0
};
struct esif_data rsp_data = {
primitive_ptr->rsp_data_type,
data_ptr + primitive_ptr->rsp_data_offset,
primitive_ptr->rsp_data_len,
0
};
/* Done this way to fix compiler warning in release build */
char tmp[8];
tmp[0] = '\0';
data_size = ipc_ptr->data_len - sizeof(*primitive_ptr);
if(((primitive_ptr->req_data_offset + primitive_ptr->req_data_len) >
data_size) ||
((primitive_ptr->rsp_data_offset + primitive_ptr->rsp_data_len) >
data_size)) {
rc = ESIF_E_NEED_LARGER_BUFFER;
goto exit;
}
ESIF_TRACE_DYN_PRIM("%s: PRIMITIVE Received:\n", ESIF_FUNC);
ESIF_TRACE_DYN_DECODE(
" Version: %d\n"
" Primitive: %s(%d)\n"
" Primitive Domain: %s(%d)\n"
" Primitive Instance: %d\n"
" Source Type/ID: %s/%d\n"
" Destination Type/ID: %s/%d\n"
" Action Hint: %s(%d)\n"
" Payload Length: %d\n"
" Request Data Type: %s(%d)\n"
" Request Data Offset: %d\n"
" Request Data Length: %d\n"
" Response Data Type: %s(%d)\n"
" Response Data Offset: %d\n"
" Response Data Length: %d\n",
(int)primitive_ptr->version,
esif_primitive_str((enum esif_primitive_type)primitive_ptr->id),
(int)primitive_ptr->id,
esif_primitive_domain_str(primitive_ptr->domain, tmp),
(int)primitive_ptr->domain,
(int)primitive_ptr->instance,
esif_primitive_src_str(primitive_ptr->src_id),
(int)primitive_ptr->src_id,
esif_primitive_dst_str(primitive_ptr->dst_id),
(int)primitive_ptr->dst_id,
esif_action_type_str(primitive_ptr->kern_action),
(int)primitive_ptr->kern_action,
(int)primitive_ptr->payload_len,
esif_data_type_str(primitive_ptr->req_data_type),
(int)primitive_ptr->req_data_type,
(int)primitive_ptr->req_data_offset,
(int)primitive_ptr->req_data_len,
esif_data_type_str(primitive_ptr->rsp_data_type),
(int)primitive_ptr->rsp_data_type,
(int)primitive_ptr->rsp_data_offset,
(int)primitive_ptr->rsp_data_len);
/* Lookup the requsted participant instance */
lp_ptr = esif_lf_pm_lp_get_by_instance_id(primitive_ptr->dst_id);
if (NULL == lp_ptr) {
rc = ESIF_E_PRIMITIVE_DST_UNAVAIL;
} else {
struct esif_primitive_tuple tuple = {
(u16)primitive_ptr->id,
primitive_ptr->domain,
primitive_ptr->instance
};
/*
* 5th param - user specified action, or all actions (if NULL)
*/
rc = esif_execute_primitive(lp_ptr,
&tuple,
&req_data,
&rsp_data,
&primitive_ptr->kern_action);
}
primitive_ptr->return_code = rc;
/* Update Response Data Length and Type (May be Changed) */
primitive_ptr->rsp_data_type = rsp_data.type;
primitive_ptr->rsp_data_len = rsp_data.data_len;
ESIF_TRACE_DYN_PRIM("%s:\n"
" PRIMITIVE Return: %s(%d)\n"
" Response Data Type: %s(%d)\n"
" Buffer Length: %d\n"
" Data Length : %d\n",
ESIF_FUNC, esif_rc_str(rc), rc,
esif_data_type_str(primitive_ptr->rsp_data_type),
rsp_data.type, rsp_data.data_len,
rsp_data.data_len);
exit:
return ipc_ptr;
}
/* Execute Primitive */
enum esif_rc esif_execute_primitive(
struct esif_lp *lp_ptr,
const struct esif_primitive_tuple *tuple_ptr,
const struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr,
const u16 *action_index_ptr
)
{
enum esif_rc rc = ESIF_OK;
struct esif_lp_primitive *primitive_ptr = NULL;
u8 action = 0;
/* Done this way to fix compiler warning in release build */
char tmp[8];
tmp[0] = '\0';
/* Special load our DSP */
if (ESIF_DATA_DSP == req_data_ptr->type) {
ESIF_TRACE_DYN_PRIM_DPF("%s: Load DSP buf=%p size=%d\n",
ESIF_FUNC,
req_data_ptr->buf_ptr,
req_data_ptr->buf_len);
/* Unload? */
if (NULL != lp_ptr->dsp_ptr && 0 == req_data_ptr->buf_len) {
ESIF_TRACE_DYN_PRIM_DPF("%s: Unload DSP %p\n",
ESIF_FUNC,
lp_ptr->dsp_ptr);
esif_dsp_unload(lp_ptr);
rc = ESIF_OK;
goto exit;
}
/* Reload? */
if (lp_ptr->dsp_ptr != NULL) {
ESIF_TRACE_DYN_PRIM_DPF(
"%s: Reload DSP buf=%p size=%d\n",
ESIF_FUNC,
req_data_ptr->buf_ptr,
req_data_ptr->buf_len);
esif_dsp_unload(lp_ptr);
}
rc = esif_dsp_load(lp_ptr, req_data_ptr);
goto exit;
}
/* Can't continue without DSP! */
if (NULL == lp_ptr->dsp_ptr) {
rc = ESIF_E_NEED_DSP;
goto exit;
}
/* Free Me! */
primitive_ptr = lp_ptr->dsp_ptr->get_primitive(lp_ptr->dsp_ptr,
tuple_ptr);
if (NULL == primitive_ptr) {
rc = ESIF_E_PRIMITIVE_NOT_FOUND_IN_DSP;
goto exit;
}
if (ESIF_PM_PARTICIPANT_STATE_REGISTERED != esif_lf_pm_lp_get_state(lp_ptr)) {
rc = ESIF_E_PRIMITIVE_DST_UNAVAIL;
goto exit;
}
ESIF_TRACE_DYN_PRIM("%s: PRIMITIVE Lookup Found in DSP (%s)\n",
ESIF_FUNC, lp_ptr->dsp_ptr->get_code(lp_ptr->dsp_ptr));
ESIF_TRACE_DYN_DECODE(" Primitive: %s(%d)\n"
" Primitive Domain: %s(%d)\n"
" Primitive Instance: %d\n"
" Opcode: %s(%d)\n"
" Actions: %d\n",
esif_primitive_str((enum esif_primitive_type)
primitive_ptr->tuple.id),
(int)primitive_ptr->tuple.id,
esif_primitive_domain_str(primitive_ptr->tuple.domain, tmp),
(int)primitive_ptr->tuple.domain,
(int)primitive_ptr->tuple.instance,
esif_primitive_opcode_str(primitive_ptr->opcode),
(int)primitive_ptr->opcode,
(int)primitive_ptr->action_count);
/* Have Action Specified */
if (NULL != action_index_ptr) {
rc = esif_lf_primitive_get_and_execute_action(primitive_ptr,
lp_ptr,
req_data_ptr,
rsp_data_ptr,
(u8) *action_index_ptr);
goto exit;
}
/* No action specified, so call actions one by one until one fires */
for (action = 0; action < primitive_ptr->action_count; action++) {
rc = esif_lf_primitive_get_and_execute_action(primitive_ptr,
lp_ptr,
req_data_ptr,
rsp_data_ptr,
action);
if ((ESIF_OK == rc) ||
(ESIF_E_NEED_LARGER_BUFFER == rc) ||
(ESIF_E_PRIMITIVE_NOT_FOUND_IN_DSP == rc)) {
break;
}
}
exit:
if (primitive_ptr)
esif_ccb_free(primitive_ptr);
return rc;
}
/*
* Simple helper function to execute a primitive that takes no special
* parameters.
*/
enum esif_rc esif_get_simple_primitive(
struct esif_lp *lp_ptr,
u16 id,
u16 domain,
u16 instance,
enum esif_data_type esif_type,
void *buffer_ptr,
u32 buffer_size
)
{
enum esif_rc rc = ESIF_OK;
struct esif_primitive_tuple tuple_get = {id, domain, instance};
struct esif_data esif_void = {ESIF_DATA_VOID, NULL, 0, 0};
struct esif_data esif_return = {esif_type,
buffer_ptr,
buffer_size,
buffer_size};
if ((NULL == lp_ptr) || (NULL == buffer_ptr)) {
rc = ESIF_E_PARAMETER_IS_NULL;
goto exit;
}
rc = esif_execute_primitive(lp_ptr,
&tuple_get,
&esif_void, &esif_return,
NULL);
exit:
return rc;
}
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,180 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_link_list.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified
* against Windows SDK/DDK included headers which we have no control over.
*
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
#define LINK_LIST_DEBUG NO_ESIF_DEBUG
/* Destroy Node */
void esif_link_list_destroy_node(struct esif_link_list_node *node_ptr)
{
esif_ccb_mempool_free(ESIF_MEMPOOL_TYPE_LIST_NODE, node_ptr);
}
/* Create Node */
struct esif_link_list_node *esif_link_list_create_node(void *data_ptr)
{
struct esif_link_list_node *new_node_ptr = NULL;
new_node_ptr = (struct esif_link_list_node *)
esif_ccb_mempool_zalloc(ESIF_MEMPOOL_TYPE_LIST_NODE);
if (NULL == new_node_ptr)
return NULL;
new_node_ptr->data_ptr = data_ptr;
new_node_ptr->next_ptr = NULL;
new_node_ptr->prev_ptr = NULL;
return new_node_ptr;
}
/* Create Linked List */
struct esif_link_list *esif_link_list_create(void)
{
struct esif_link_list *new_link_list_ptr = NULL;
new_link_list_ptr = (struct esif_link_list *)
esif_ccb_mempool_zalloc(ESIF_MEMPOOL_TYPE_LIST);
if (NULL == new_link_list_ptr)
return NULL;
new_link_list_ptr->head_ptr = NULL;
new_link_list_ptr->tail_ptr = NULL;
new_link_list_ptr->nodes = 0;
return new_link_list_ptr;
}
/* Destroy Linked List */
void esif_link_list_destroy(struct esif_link_list *list_ptr)
{
struct esif_link_list_node *curr_ptr = list_ptr->head_ptr;
while (curr_ptr) {
struct esif_link_list_node *next_node_ptr = curr_ptr->next_ptr;
esif_link_list_destroy_node(curr_ptr);
curr_ptr = next_node_ptr;
}
esif_ccb_mempool_free(ESIF_MEMPOOL_TYPE_LIST, list_ptr);
}
/* Add Linked List Node */
void esif_link_list_node_add(
struct esif_link_list *list_ptr,
struct esif_link_list_node *new_node_ptr
)
{
if (NULL == list_ptr->head_ptr) {
list_ptr->head_ptr = new_node_ptr;
list_ptr->head_ptr->next_ptr = NULL;
list_ptr->head_ptr->prev_ptr = NULL;
list_ptr->tail_ptr = list_ptr->head_ptr;
} else {
new_node_ptr->prev_ptr = list_ptr->tail_ptr;
list_ptr->tail_ptr->next_ptr = new_node_ptr;
list_ptr->tail_ptr = new_node_ptr;
list_ptr->tail_ptr->next_ptr = NULL;
}
list_ptr->nodes++;
}
/* Init */
enum esif_rc esif_link_list_init(void)
{
struct esif_ccb_mempool *mempool_ptr = NULL;
LINK_LIST_DEBUG("%s: Initialize Primitive Link List\n", ESIF_FUNC);
mempool_ptr =
esif_ccb_mempool_create(ESIF_MEMPOOL_TYPE_LIST,
ESIF_MEMPOOL_FW_LIST,
sizeof(struct esif_link_list));
if (NULL == mempool_ptr)
return ESIF_E_NO_MEMORY;
mempool_ptr =
esif_ccb_mempool_create(ESIF_MEMPOOL_TYPE_LIST_NODE,
ESIF_MEMPOOL_FW_LIST_NODE,
sizeof(struct esif_link_list_node));
if (NULL == mempool_ptr)
return ESIF_E_NO_MEMORY;
return ESIF_OK;
}
/* Exit */
void esif_link_list_exit(void)
{
LINK_LIST_DEBUG("%s: Exit Primitive Link List\n", ESIF_FUNC);
}
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,105 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_LINK_LIST_H_
#define _ESIF_LINK_LIST_H_
#include "esif.h"
/* Link List Node */
struct esif_link_list_node {
void *data_ptr;
struct esif_link_list_node *next_ptr;
struct esif_link_list_node *prev_ptr;
};
/* Link List */
struct esif_link_list {
struct esif_link_list_node *head_ptr;
struct esif_link_list_node *tail_ptr;
u32 nodes;
};
#ifdef __cplusplus
extern "C" {
#endif
/* Linked List Node */
struct esif_link_list_node *esif_link_list_create_node(void *data_ptr);
void esif_link_list_destroy_node(struct esif_link_list_node *node_ptr);
/* Linked List */
struct esif_link_list *esif_link_list_create(void);
void esif_link_list_destroy(struct esif_link_list *list_ptr);
void esif_link_list_node_add(struct esif_link_list *list_ptr,
struct esif_link_list_node *new_node_ptr);
/* Init */
enum esif_rc esif_link_list_init(void);
void esif_link_list_exit(void);
#ifdef __cplusplus
}
#endif
#ifdef ESIF_ATTR_USER
typedef struct esif_link_list EsifLinkList, *EsifLinkListPtr,
**EsifLinkListPtrLocation;
#endif
#endif /* _ESIF_LINK_LIST_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,140 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_MEMPOOL_H_
#define _ESIF_MEMPOOL_H_
#ifdef ESIF_ATTR_USER
#include "esif.h"
#endif
/* Memory Pools */
enum esif_mempool_type {
ESIF_MEMPOOL_TYPE_DATA = 0, /* Data */
ESIF_MEMPOOL_TYPE_DSP, /* Device Support Package */
ESIF_MEMPOOL_TYPE_HASH, /* Hash Table */
ESIF_MEMPOOL_TYPE_LIST, /* Linked List */
ESIF_MEMPOOL_TYPE_LIST_NODE, /* Linked List Node */
ESIF_MEMPOOL_TYPE_PM, /* Participant Manager */
ESIF_MEMPOOL_TYPE_QUEUE, /* Queue */
ESIF_MEMPOOL_TYPE_MAX /* Max */
};
/*
* Windows Uses a 32 Bit Value To Represent A Tag. Linux allows for a name
* we acommodate both heree in addition Windows does not have a number authority
* so we resuse permutations of ESIF to avoid name space collisions.
* For Windows use Poolmon or ESIF Tools to Monitor
* For Linux use Slabtop or ESIF tools to Monitor (@ Hutts To Top Of Slabtop)
* Note you may bave to boot the kernel with slub debug on or Linux will
* consolidate same size cahches.
*/
/* Driver */
#define ESIF_MEMPOOL_DRIVER_LF 'fise' /* esif Bit 0000 Lower Framework */
#define ESIF_MEMPOOL_DRIVER_ACPI 'Fise' /* esif Bit 0001 ACPI Driver */
#define ESIF_MEMPOOL_DRIVER_CPU 'fIse' /* esif Bit 0010 CPU Driver */
#define ESIF_MEMPOOL_DRIVER_PCH 'FIse' /* esif Bit 0011 PCH Driver */
#define ESIF_MEMPOOL_DRIVER_PLAT 'fiSe' /* esif Bit 0100 PLAT Driver */
#define ESIF_MEMPOOL_DRIVER_RESERVED1 'FiSe' /* esif Bit 0101 PLAT Driver */
/* ESIF Framework */
#define ESIF_MEMPOOL_FW_PM 'fisE' /* ESIF Bit 1000 Participant */
#define ESIF_MEMPOOL_FW_DATA 'FisE' /* ESIF Bit 1001 Data */
#define ESIF_MEMPOOL_FW_DSP 'FIsE' /* ESIF Bit 1011 Dsp */
#define ESIF_MEMPOOL_FW_HASH 'fISe' /* esif Bit 0110 Hash */
#define ESIF_MEMPOOL_FW_QUEUE 'fiSE' /* ESIF Bit 1100 Queue */
#define ESIF_MEMPOOL_FW_LIST 'FiSE' /* ESIF Bit 1101 List */
#define ESIF_MEMPOOL_FW_LIST_NODE 'fISE' /* ESIF Bit 1110 List Node */
#define ESIF_MEMPOOL_FW_MALLOC 'FISE' /* ESIF Bit 1111 Gen Malloc Pool */
static ESIF_INLINE char *esif_mempool_str(u32 pool_tag)
{
#define ESIF_CREATE_MEMPOOL(mp, mpd, str) case mp: str = (esif_string)mpd; break;
esif_string str = (esif_string)ESIF_NOT_AVAILABLE;
switch (pool_tag) {
ESIF_CREATE_MEMPOOL(ESIF_MEMPOOL_DRIVER_LF, "@esif_lf_driver", str)
ESIF_CREATE_MEMPOOL(ESIF_MEMPOOL_DRIVER_ACPI, "@esif_acpi_driver", str)
ESIF_CREATE_MEMPOOL(ESIF_MEMPOOL_DRIVER_CPU, "@esif_cpu_driver", str)
ESIF_CREATE_MEMPOOL(ESIF_MEMPOOL_DRIVER_PCH, "@esif_pch_driver", str)
ESIF_CREATE_MEMPOOL(ESIF_MEMPOOL_DRIVER_PLAT, "@esif_plat_driver", str)
ESIF_CREATE_MEMPOOL(ESIF_MEMPOOL_DRIVER_RESERVED1, "@esif_rsv1_driver", str)
ESIF_CREATE_MEMPOOL(ESIF_MEMPOOL_FW_HASH, "@esif_hash_table_cache", str)
ESIF_CREATE_MEMPOOL(ESIF_MEMPOOL_FW_PM, "@esif_pm_cache", str)
ESIF_CREATE_MEMPOOL(ESIF_MEMPOOL_FW_DATA, "@esif_data_cache", str)
ESIF_CREATE_MEMPOOL(ESIF_MEMPOOL_FW_DSP, "@esif_dsp_cache", str)
ESIF_CREATE_MEMPOOL(ESIF_MEMPOOL_FW_QUEUE, "@esif_queue_cache", str)
ESIF_CREATE_MEMPOOL(ESIF_MEMPOOL_FW_LIST, "@esif_list_cache", str)
ESIF_CREATE_MEMPOOL(ESIF_MEMPOOL_FW_LIST_NODE, "@esif_list_node_cache", str)
ESIF_CREATE_MEMPOOL(ESIF_MEMPOOL_FW_MALLOC, "@esif_malloc_cache", str)
}
return str;
}
#ifdef __cplusplus
extern "C" {
#endif
extern struct esif_ccb_mempool *g_mempool[ESIF_MEMPOOL_TYPE_MAX];
#ifdef __cplusplus
}
#endif
#endif /* _ESIF_MEMPOOL_H_ */
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,327 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_MEMTYPE_H_
#define _ESIF_MEMTYPE_H_
#ifdef ESIF_ATTR_USER
#include "esif.h"
#endif
/* Variable Length Common Memory Types */
enum esif_memtype_type {
ESIF_MEMTYPE_TYPE_EVENT = 0, /* Event */
ESIF_MEMTYPE_TYPE_MAX
};
#ifdef __cplusplus
extern "C" {
#endif
/* Implemented in esif_lf.c */
extern struct esif_ccb_memtype *g_memtype[ESIF_MEMTYPE_TYPE_MAX];
extern esif_ccb_lock_t g_memtype_lock;
#ifdef __cplusplus
}
#endif
static ESIF_INLINE char *esif_memtype_str(u32 type)
{
#define ESIF_CREATE_MEMTYPE(mp, mpd, str) case mp: str = (esif_string)mpd; break;
esif_string str = (esif_string)ESIF_NOT_AVAILABLE;
switch (type) {
ESIF_CREATE_MEMTYPE(ESIF_MEMTYPE_TYPE_EVENT, "esif_event_dynamic", str)
}
return str;
}
static ESIF_INLINE struct esif_ccb_memtype *esif_ccb_memtype_create(
enum esif_memtype_type type_tag);
static ESIF_INLINE void esif_ccb_memtype_destroy(
enum esif_memtype_type type_tag);
#pragma pack(push,1)
/* Memory Type Not Fixed Size Use Mempool For That */
struct esif_ccb_memtype {
esif_string name_ptr; /* Name */
u32 type_tag; /* Type Of Memory */
u32 alloc_count; /* Allocation Count */
u32 free_count; /* Free Count */
};
#pragma pack(pop)
static ESIF_INLINE void esif_ccb_memtype_init_tracking(void)
{
u32 type_tag;
esif_ccb_lock_init(&g_memtype_lock);
/*
* Create the tracking array for all supported types.
*/
for (type_tag = 0; type_tag < ESIF_MEMTYPE_TYPE_MAX; type_tag++)
esif_ccb_memtype_create((enum esif_memtype_type)type_tag);
}
static ESIF_INLINE void esif_ccb_memtype_uninit_tracking(void)
{
u32 type_tag;
/*
* Create the tracking array for all supported types.
*/
for (type_tag = 0; type_tag < ESIF_MEMTYPE_TYPE_MAX; type_tag++)
esif_ccb_memtype_destroy((enum esif_memtype_type)type_tag);
esif_ccb_lock_uninit(&g_memtype_lock);
}
/* Memory Type Create */
static ESIF_INLINE struct esif_ccb_memtype *esif_ccb_memtype_create(
enum esif_memtype_type type_tag
)
{
struct esif_ccb_memtype *memtype_ptr = NULL;
if (type_tag >= ESIF_MEMTYPE_TYPE_MAX)
goto exit;
memtype_ptr = (struct esif_ccb_memtype *)
esif_ccb_malloc(sizeof(*memtype_ptr));
if (NULL == memtype_ptr)
goto exit;
memtype_ptr->type_tag = type_tag;
memtype_ptr->name_ptr = esif_memtype_str(type_tag);
memtype_ptr->alloc_count = 0;
memtype_ptr->free_count = 0;
esif_ccb_write_lock(&g_memtype_lock);
g_memtype[type_tag] = memtype_ptr;
#ifdef ESIF_ATTR_KERNEL
memstat_inc(&g_memstat.memTypeAllocs);
#endif
esif_ccb_write_unlock(&g_memtype_lock);
MEMTYPE_DEBUG("%s: Memory Type %s Create\n",
ESIF_FUNC,
memtype_ptr->name_ptr);
exit:
return memtype_ptr;
}
/* Memory Type Destroy */
static ESIF_INLINE void esif_ccb_memtype_destroy(
enum esif_memtype_type type_tag
)
{
u32 remain = 0;
struct esif_ccb_memtype *memtype_ptr = NULL;
if (type_tag >= ESIF_MEMTYPE_TYPE_MAX)
goto exit;
esif_ccb_write_lock(&g_memtype_lock);
memtype_ptr = g_memtype[type_tag];
if (NULL == memtype_ptr) {
esif_ccb_write_unlock(&g_memtype_lock);
goto exit;
}
remain = memtype_ptr->alloc_count - memtype_ptr->free_count;
MEMPOOL_DEBUG("%s: Memory Type %s Destroy alloc=%d free=%d remain=%d\n",
ESIF_FUNC,
memtype_ptr->name_ptr,
memtype_ptr->alloc_count,
memtype_ptr->free_count,
remain);
#ifdef ESIF_ATTR_KERNEL
memstat_inc(&g_memstat.memTypeFrees);
#endif
esif_ccb_free(memtype_ptr);
g_memtype[type_tag] = NULL;
esif_ccb_write_unlock(&g_memtype_lock);
exit:
;
}
/* Memory Type Allocate */
static ESIF_INLINE void *esif_ccb_memtype_alloc(
enum esif_memtype_type type_tag,
u32 size
)
{
void *mem_ptr = NULL;
struct esif_ccb_memtype *memtype_ptr = NULL;
/*
* Attempt allocation first, so if unsuccessful updating stats we still
* return usable memory.
*/
mem_ptr = esif_ccb_malloc(size);
if (NULL == mem_ptr)
goto exit;
if (type_tag >= ESIF_MEMTYPE_TYPE_MAX)
goto exit;
esif_ccb_write_lock(&g_memtype_lock);
memtype_ptr = g_memtype[type_tag];
if (NULL == memtype_ptr) {
esif_ccb_write_unlock(&g_memtype_lock);
goto exit;
}
memtype_ptr->alloc_count++;
#ifdef ESIF_ATTR_KERNEL
memstat_inc(&g_memstat.memTypeObjAllocs);
#endif
MEMPOOL_DEBUG("%s: MT Entry Allocated(%d)=%p From Memtype %s\n",
ESIF_FUNC,
memtype_ptr->alloc_count,
mem_ptr,
memtype_ptr->name_ptr);
esif_ccb_write_unlock(&g_memtype_lock);
exit:
return mem_ptr;
}
/* Memory Type ZERO Allocate */
static ESIF_INLINE void *esif_ccb_memtype_zalloc(
enum esif_memtype_type type_tag,
u32 size
)
{
void *mem_ptr = NULL;
mem_ptr = esif_ccb_memtype_alloc(type_tag, size);
if (NULL == mem_ptr)
goto exit;
esif_ccb_memset(mem_ptr, 0, size);
exit:
return mem_ptr;
}
/* Memory Type Free */
static ESIF_INLINE void esif_ccb_memtype_free (
enum esif_memtype_type type_tag,
void *mem_ptr
)
{
struct esif_ccb_memtype *memtype_ptr = NULL;
/*
* Deallocate first, so even if we fail to update stats, the memory
* is still freed.
*/
if (mem_ptr != NULL)
esif_ccb_free(mem_ptr);
if (type_tag >= ESIF_MEMTYPE_TYPE_MAX)
goto exit;
esif_ccb_write_lock(&g_memtype_lock);
memtype_ptr = g_memtype[type_tag];
if (NULL == memtype_ptr) {
esif_ccb_write_unlock(&g_memtype_lock);
goto exit;
}
memtype_ptr->free_count++;
#ifdef ESIF_ATTR_KERNEL
memstat_inc(&g_memstat.memTypeObjFrees);
#endif
MEMPOOL_DEBUG("%s: MT Entry Freed(%d)=%p From Memtype %s\n", ESIF_FUNC,
memtype_ptr->free_count, mem_ptr, memtype_ptr->name_ptr);
esif_ccb_write_unlock(&g_memtype_lock);
exit:
;
}
#endif /* _ESIF_MEMTYPE_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,165 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_PARTICIPANT_H_
#define _ESIF_PARTICIPANT_H_
#include "esif.h"
#include "esif_participant_iface.h"
#include "esif_event.h"
#define ESIF_PARTICIPANT_INVALID_TYPE 0xFFFFFFFF
#define ESIF_PARTICIPANT_INVALID_UID ""
#ifdef ESIF_ATTR_KERNEL
#include "esif_dsp.h"
#include "esif_temp.h"
#include "esif_power.h"
#include "esif_primitive.h"
#include "esif_lf_domain.h"
/*
** TODO: Hookup CCB Debug
*/
/* Lower Participant */
#ifndef ESIF_ATTR_OS_LINUX_DRIVER
struct esif_lp {
u8 instance; /* Lower Participant Instance */
char pi_name[ESIF_NAME_LEN]; /* PI Name */
struct esif_participant_iface *pi_ptr; /* Particpant INTERFACE */
u8 enable; /* Boolean Enable Disable */
struct esif_lp_dsp *dsp_ptr; /* DSP */
/* Number Of Qualifiers For A Participant */
u8 domain_count;
/* Domains For Participants */
struct esif_lp_domain domains[ESIF_DOMAIN_MAX];
/* XFORM Temperature */
enum esif_rc (*xform_temp)(const enum esif_temperature_type,
esif_temp_t *temp,
const enum esif_action_type action,
const struct esif_lp_dsp *dsp,
const struct esif_lp_primitive *primitive_ptr,
const struct esif_lp *lp_ptr);
/* XFORM Power */
enum esif_rc (*xform_power)(const enum esif_power_unit_type,
esif_power_t *power,
const enum esif_action_type action,
const struct esif_lp_dsp *dsp,
const enum esif_primitive_opcode opcode);
};
#endif /* ESIF_ATTR_OS_LINUX_DRIVER */
#endif /* ESIF ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
#include "esif_uf_app_iface.h"
typedef enum {
eParticipantOriginLF,
eParticipantOriginUF
} eEsifParticipantOrigin;
/* Upper Particpant Data. Everything we know about a participant */
typedef struct _t_EsifUpData {
/* Common */
esif_ver_t fVersion; /* Version */
esif_guid_t fDriverType; /* Driver Type */
char fName[ESIF_NAME_LEN]; /* Friendly Name */
char fDesc[ESIF_DESC_LEN]; /* Description */
char fDriverName[ESIF_NAME_LEN]; /* Driver Name */
char fDeviceName[ESIF_NAME_LEN]; /* Device Name */
char fDevicePath[ESIF_PATH_LEN]; /* Device Path
* /sys/bus/platform...*/
enum esif_participant_enum fEnumerator; /* Device Enumerator If Any */
esif_flags_t fFlags; /* Flags If Any */
/* ACPI */
char fAcpiDevice[ESIF_NAME_LEN]; /* Device INT340X */
char fAcpiScope[ESIF_SCOPE_LEN]; /* Scope/REGEX e.g. \_SB.PCI0.TPCH */
char fAcpiUID[ESIF_ACPI_UID_LEN]; /* Unique ID If Any */
eDomainType fAcpiType; /* Participant Type If Any */
/* PCI */
UInt16 fPciVendor; /* PCI Vendor e.g. 0x8086 For Intel */
UInt16 fPciDevice; /* Device ID Unique To Vendor */
UInt8 fPciBus; /* Bus This Device Resides On */
UInt8 fPciBusDevice; /* Device Number On Bus */
UInt8 fPciFunction; /* Function Of Device */
UInt8 fPciRevision; /* Revision Of PCI Hardware Device */
UInt8 fPciClass; /* Class 3 bytes: (base class,sub sclass, prog-if) */
UInt8 fPciSubClass; /* Sub Class */
UInt8 fPciProgIf; /* Program Interface */
} EsifUpData, *EsifUpDataPtr, **EsifUpDataPtrLocation;
/* Upper Participant */
typedef struct _t_EsifUp {
UInt8 fInstance; /* Unique Upper Participant Instance */
UInt8 fLpInstance; /* Lower Participant Instance */
void *fUpHandle; /* Upper Participant Handle */
UInt8 fEnabled; /* Enabled / Disabled */
eEsifParticipantOrigin fOrigin; /* Origin Of Creation */
struct esif_up_dsp *fDspPtr; /* Pointer To Our DSP */
EsifUpData fMetadata; /* Participant Data */
} EsifUp, *EsifUpPtr, **EsifUpPtrLocation;
#endif /* ESIF_ATTR_USER */
#endif /* _ESIF_PARTICIPANT_H_ */
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,147 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_PARTICIPANT_IFACE_H_
#define _ESIF_PARTICIPANT_IFACE_H_
#include "esif.h"
#include "esif_event.h"
/* Context Registration Functions */
#define ESIF_PARTICIPANT_VERSION 1
#ifdef ESIF_ATTR_KERNEL
/* Flags */
#define ESIF_FLAG_DPTFZ 0x1 /* Participant Is Actually A DPTF Zone */
/* Participant INTERFACE */
struct esif_participant_iface {
esif_ver_t version; /* Version */
esif_guid_t class_guid; /* Class GUID */
enum esif_participant_enum enumerator; /* Device Enumerator If Any */
esif_flags_t flags; /* Flags If Any
* */
char name[ESIF_NAME_LEN]; /* Friendly Name */
char desc[ESIF_DESC_LEN]; /* Description */
char driver_name[ESIF_NAME_LEN]; /* Driver Name */
char device_name[ESIF_NAME_LEN]; /* Device Name */
char device_path[ESIF_PATH_LEN]; /* Device Path /sys/bus/platform...*/
/* EVENT Send Event From Driver To Framework */
enum esif_rc (*send_event)(struct esif_participant_iface *pi,
enum esif_event_type type, u16 domain,
struct esif_data *data);
/* EVENT Receive Event From Framework To Driver */
enum esif_rc (*recv_event)(enum esif_event_type type, u16 domain,
struct esif_data *data);
/* ACPI */
char acpi_device[ESIF_SCOPE_LEN];/* Device INT340X */
char acpi_scope[ESIF_SCOPE_LEN]; /* Scope/REGEX e.g. \_SB.PCI0.TPCH */
char acpi_uid[ESIF_ACPI_UID_LEN]; /* Unique ID If Any */
u32 acpi_type; /* Participant Type If Any */
/* PCI */
u32 pci_vendor; /* PCI Vendor e.g. 0x8086 For Intel */
u32 pci_device; /* Device ID Unique To Vendor */
u8 pci_bus; /* Bus This Device Resides On */
u8 pci_bus_device; /* Device Number On Bus */
u8 pci_function; /* Function Of Device */
u8 pci_revision; /* Revision Of PCI Hardware Device */
u8 pci_class; /* Class 3 bytes: (base class,sub sclass, prog-if) */
u8 pci_sub_class; /* Sub Class */
u8 pci_prog_if; /* Program Interface */
esif_device_t device; /* Os Agnostic Driver Context */
void __iomem *mem_base; /* MMIO/MCHBAR Address */
u32 mem_size; /* MMIO/MCHBAR Size */
acpi_handle acpi_handle; /* ACPI Handle */
};
#endif /* ESIF ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
#pragma pack(push,1)
/* Conjure Participant INTERFACE */
typedef struct _t_EsifParticipantIface {
esif_ver_t version; /* Version */
esif_guid_t class_guid; /* Class GUID */
enum esif_participant_enum enumerator; /* Device Enumerator If Any */
esif_flags_t flags; /* Flags If Any */
char name[ESIF_NAME_LEN]; /* Friendly Name */
char desc[ESIF_DESC_LEN]; /* Description */
char driver_name[ESIF_NAME_LEN]; /* Driver Name */
char device_name[ESIF_NAME_LEN]; /* Device Name */
char device_path[ESIF_PATH_LEN]; /* Device Path /sys/bus/platform...*/
char object_id[ESIF_SCOPE_LEN]; /* Scope/REGEX e.g.\_UF.CNJR.WIDI */
/* EVENT Send Event From Conjure To Framework */
enum esif_rc (ESIF_CALLCONV *send_event)(struct _t_EsifParticipantIface *pi,
enum esif_event_type type, void *data);
/* EVENT Receive Event From Framework To Conjure */
enum esif_rc (ESIF_CALLCONV *recv_event)(enum esif_event_type type, void *data);
} EsifParticipantIface, *EsifParticipantIfacePtr,
**EsifParticipantIfacePtrLocation;
#pragma pack(pop)
#endif /* ESIF_ATTR_USER */
#endif /* _ESIF_PARTICIPANT_IFACE_H_ */
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,224 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_PM_H_
#define _ESIF_PM_H_
#include "esif.h"
#include "esif_participant.h"
/*
*******************************************************************************
** AGNOSTIC KERNEL/USER
*******************************************************************************
*/
/* Maximum Participant Entries */
#define MAX_PARTICIPANT_ENTRY 20
/* Participant Instances */
#define ESIF_INSTANCE_LF 0 /* Reserved For ESIF Lower Framework */
#define ESIF_INSTANCE_FIRST 1 /* The First Useable Instance */
#define ESIF_INSTANCE_UF 254 /* Reserved For ESIF Upper Framework */
#define ESIF_INSTANCE_BROADCAST 255 /* Send To All ESIF Instances */
/* Participant State Machine States */
enum esif_pm_participant_state {
/* Slot is open and never been used */
ESIF_PM_PARTICIPANT_STATE_AVAILABLE = 0,
/* Removed participant */
ESIF_PM_PARTICIPANT_REMOVED,
/* Created Lower Participant Instance */
ESIF_PM_PARTICIPANT_STATE_CREATED,
/* In The Process Of Registering */
ESIF_PM_PARTICIPANT_STATE_REGISTERING, /* Notifying UF and part. */
ESIF_PM_PARTICIPANT_STATE_NEEDDSP, /* DSP unloaded */
ESIF_PM_PARTICIPANT_STATE_REGISTERED, /* DSP Ready */
ESIF_PM_PARTICIPANT_STATE_SUSPENDED, /* Part out of D0 */
ESIF_PM_PARTICIPANT_STATE_RESUMED /* Returned to D0 */
};
/* Participant State Machine Descriptions */
static ESIF_INLINE esif_string esif_pm_participant_state_str(
enum esif_pm_participant_state state)
{
#define CREATE_STATE(ps, psd, str) case ps: str = (esif_string) psd; break;
esif_string str = (esif_string)ESIF_NOT_AVAILABLE;
switch (state) {
CREATE_STATE(ESIF_PM_PARTICIPANT_STATE_AVAILABLE, "AVAILABLE", str)
CREATE_STATE(ESIF_PM_PARTICIPANT_REMOVED, "REMOVED", str)
CREATE_STATE(ESIF_PM_PARTICIPANT_STATE_CREATED, "CREATED", str)
CREATE_STATE(ESIF_PM_PARTICIPANT_STATE_REGISTERING, "REGISTERING", str)
CREATE_STATE(ESIF_PM_PARTICIPANT_STATE_NEEDDSP, "NEED_DSP", str)
CREATE_STATE(ESIF_PM_PARTICIPANT_STATE_REGISTERED, "REGISTERED", str)
CREATE_STATE(ESIF_PM_PARTICIPANT_STATE_SUSPENDED, "SUSPENDED", str)
CREATE_STATE(ESIF_PM_PARTICIPANT_STATE_RESUMED, "RESUMED", str)
}
return str;
}
/*
*******************************************************************************
** KERNEL - Lower Framework Lower Participant (esif_lf_pm.c)
*******************************************************************************
*/
#ifdef ESIF_ATTR_KERNEL
/* Get State */
enum esif_pm_participant_state esif_lf_pm_lp_get_state(
/* Lower Participant Intance */
const struct esif_lp *lp_ptr);
/* Set State */
enum esif_rc esif_lf_pm_lp_set_state(
/* Lower Participant Instance */
struct esif_lp *lp_ptr,
/* Particpant State Enumeration*/
const enum esif_pm_participant_state state);
/* Get LP Instance By ID */
struct esif_lp *esif_lf_pm_lp_get_by_instance_id(const u8 id);
/* Get Interface By ID */
struct esif_participant_iface *esif_lf_pm_pi_get_by_instance_id(const u8 id);
/* Get LP By PI Pointer */
struct esif_lp *esif_lf_pm_lp_get_by_pi(
/* Participant Interface */
const struct esif_participant_iface *pi_ptr);
/* Create Participant */
struct esif_lp *esif_lf_pm_lp_create(
/* Participant Interface */
struct esif_participant_iface *pi_ptr);
/* Remove Participant */
void esif_lf_pm_lp_remove(
/* Lower Participant */
struct esif_lp *lp_ptr);
/* Participant Manager Init */
enum esif_rc esif_lf_pm_init(void);
/* Participant Manager Exit */
void esif_lf_pm_exit(void);
#endif /* ESIF_ATTR_KERNEL */
/*
*******************************************************************************
** USER - Upper Framework Upper Participant (esif_uf_pm.c)
*******************************************************************************
*/
#ifdef ESIF_ATTR_USER
/* Participant Manager Entry */
typedef struct _t_EsifUpManagerEntry {
enum esif_pm_participant_state fState;
EsifUpPtr fUpPtr;
} EsifUpManagerEntry, *EsifUpManagerEntryPtr, **EsifUpManagerEntryPtrLocation;
/* Package Manager */
typedef struct _t_EsifUppMgr {
UInt8 fEntryCount;
EsifUpManagerEntry fEntries[MAX_PARTICIPANT_ENTRY];
esif_ccb_lock_t fLock;
} EsifUppMgr, *EsifUppMgrPtr, **EsifUppMgrPtrLocation;
#ifdef __cplusplus
extern "C" {
#endif
EsifUpPtr EsifUpManagerGetAvailableParticipantByInstance(const UInt8 instance);
Bool EsifUpManagerDoesAvailableParticipantExistByName(char *participantName);
EsifUpPtr EsifUpManagerGetAvailableParticipantByName(char *participantName);
EsifUpPtr EsifUpManagerCreateParticipant(
const eEsifParticipantOrigin origin,
const void *handle,
const void *metadataPtr
);
eEsifError EsifUpManagerUnregisterParticipant(
const eEsifParticipantOrigin origin,
const void *handle
);
eEsifError EsifUpManagerMapLpidToPartHandle(
const UInt8 lpInstance,
void *participantHandle
);
typedef struct _t_EsifApp *EsifAppPtr;
eEsifError EsifUpManagerRegisterParticipantsWithApp(EsifAppPtr aAppPtr);
eEsifError EsifUpManagerDestroyParticipantsInApp(EsifAppPtr aAppPtr);
eEsifError EsifUppMgrInit(void);
void EsifUppMgrExit(void);
#ifdef __cplusplus
}
#endif
#endif /* ESIF_ATTR_USER */
#endif /* _ESIF_PM_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,225 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_POWER_H_
#define _ESIF_POWER_H_
#include "esif_primitive.h"
#include "esif_dsp.h"
#define POWER_DEBUG 14 /* Debug Module Level */
#ifdef ESIF_ATTR_KERNEL
#define ESIF_TRACE_DYN_POWER(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ELF, POWER_DEBUG, format, ##__VA_ARGS__)
#endif /* ESIF_ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
/*
* TODO: User mode does not currently support this debug area.
* Need to update when user mode unified debug infrastructre
* is in place.
*/
#define ESIF_TRACE_DYN_POWER NO_ESIF_DEBUG
#endif /* ESIF_ATTR_USER */
/* Power Unit Type */
enum esif_power_unit_type {
ESIF_POWER_W = 0, /* Watts */
ESIF_POWER_DECIW, /* Deci Watts .1 Watts */
ESIF_POWER_CENTIW, /* Centi Watts .01 Watts */
ESIF_POWER_MILLIW, /* Milli Watts .001 Watts */
ESIF_POWER_UNIT_ATOM, /* 1 * (2 ^ RAPL_POWER_UNIT) */
ESIF_POWER_UNIT_CORE /* 1 / (2 ^ RAPL_POWER_UNIT) */
};
/* Power Unit Type String */
static ESIF_INLINE esif_string esif_power_unit_type_str(
enum esif_power_unit_type type)
{
#define ESIF_CREATE_POWER_UNIT_TYPE(t, str) case t: str = #t; break;
esif_string str = ESIF_NOT_AVAILABLE;
switch (type) {
ESIF_CREATE_POWER_UNIT_TYPE(ESIF_POWER_W, str)
ESIF_CREATE_POWER_UNIT_TYPE(ESIF_POWER_DECIW, str)
ESIF_CREATE_POWER_UNIT_TYPE(ESIF_POWER_CENTIW, str)
ESIF_CREATE_POWER_UNIT_TYPE(ESIF_POWER_MILLIW, str)
ESIF_CREATE_POWER_UNIT_TYPE(ESIF_POWER_UNIT_ATOM, str)
ESIF_CREATE_POWER_UNIT_TYPE(ESIF_POWER_UNIT_CORE, str)
}
return str;
}
/* Power Unit Description */
static ESIF_INLINE esif_string esif_power_unit_desc(
enum esif_power_unit_type type)
{
#define ESIF_CREATE_POWER_UNIT_DESC(t, td, str) case t: str = td; break;
esif_string str = ESIF_NOT_AVAILABLE;
switch (type) {
ESIF_CREATE_POWER_UNIT_DESC(ESIF_POWER_W, "Watts", str)
ESIF_CREATE_POWER_UNIT_DESC(ESIF_POWER_DECIW, "DeciW", str)
ESIF_CREATE_POWER_UNIT_DESC(ESIF_POWER_CENTIW, "CentiW", str)
ESIF_CREATE_POWER_UNIT_DESC(ESIF_POWER_MILLIW, "MilliW", str)
ESIF_CREATE_POWER_UNIT_DESC(ESIF_POWER_UNIT_ATOM, "UnitAtom", str)
ESIF_CREATE_POWER_UNIT_DESC(ESIF_POWER_UNIT_CORE, "UnitCore", str)
}
return str;
}
/*
* Select Power Unit To Normalize Power To.
*/
/* DPTF Wants Everything In Milli Watts */
#define NORMALIZE_POWER_UNIT_TYPE ESIF_POWER_MILLIW
/* Normalize Power To Watts. */
static ESIF_INLINE int esif_convert_power(
enum esif_power_unit_type in,
enum esif_power_unit_type out,
esif_power_t *power_ptr
)
{
esif_power_t val = 0;
if (NULL == power_ptr)
return ESIF_E_PARAMETER_IS_NULL;
val = *power_ptr;
if (val == 0 || in == out)
return ESIF_OK;
/* For the sake of interger operation, do mutiple before divid
* (37/8)*1000 = 4000, (34/8)*1000 = 4000 (less precise)
* (37*1000)/8 = 4625, (34*1000)/8 = 4250 (more precise)
*/
/* Convert To Output */
switch (out) {
case ESIF_POWER_MILLIW:
val *= 1000;
break;
case ESIF_POWER_CENTIW:
val *= 100;
break;
case ESIF_POWER_DECIW:
val *= 10;
break;
case ESIF_POWER_UNIT_ATOM:
val *= 32; /* RAPL_POWER_UNIT = 5 1 * (2 ^ POWER_UNIT) = 32 */
/* LIFU TODO Get Power Unit From GET_RAPL_POWER_UNIT */
break;
case ESIF_POWER_UNIT_CORE:
val *= 8; /* RAPL_POWER_UNIT = 3 1 * (2 ^ POWER_UNIT) = 8 */
/* LIFU TODO Get Power Unit From GET_RAPL_POWER_UNIT */
break;
case ESIF_POWER_W:
break;
default:
return ESIF_E_UNSUPPORTED_RESULT_POWER_TYPE;
}
/* Normalize To Watts */
switch (in) {
case ESIF_POWER_MILLIW:
val /= 1000;
break;
case ESIF_POWER_CENTIW:
val /= 100;
break;
case ESIF_POWER_DECIW:
val /= 10;
break;
case ESIF_POWER_UNIT_ATOM:
val /= 32; /* RAPL_POWER_UNIT - 5 1 / (2 ^ (POWER_UNIT) = 32 */
/* LIFU TODO Get Power Unit From GET_RAPL_POWER_UNIT */
break;
case ESIF_POWER_UNIT_CORE:
val /= 8; /* RAPL_POWER_UNIT = 3 1 / (2 ^ (POWER_UNIT) = 8 */
/* LIFU TODO Get Power Unit From GET_RAPL_POWER_UNIT */
break;
case ESIF_POWER_W:
break;
default:
return ESIF_E_UNSUPPORTED_REQUEST_POWER_TYPE;
}
*power_ptr = val;
return ESIF_OK;
}
#endif /* _ESIF_POWER_H_ */
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,137 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_LF_PRIMITIVE_H_
#define _ESIF_LF_PRIMITIVE_H_
#include "esif.h"
#define ESIF_PRIMITIVE_VERSION 1
/* Primitive Opcodes */
enum esif_primitive_opcode {
ESIF_PRIMITIVE_OP_GET = 1,
ESIF_PRIMITIVE_OP_SET
};
/* Primitive Opcodes String */
static ESIF_INLINE esif_string esif_primitive_opcode_str (
enum esif_primitive_opcode opcode)
{
#define CREATE_PRIMITIVE_OPCODE(oc, str) case oc: str = (char *) #oc; break;
esif_string str = (esif_string)ESIF_NOT_AVAILABLE;
switch (opcode) {
CREATE_PRIMITIVE_OPCODE(ESIF_PRIMITIVE_OP_GET, str)
CREATE_PRIMITIVE_OPCODE(ESIF_PRIMITIVE_OP_SET, str)
}
return str;
}
#pragma pack(push, 1)
struct esif_primitive_tuple {
u16 id; /* GET_TEMP */
u16 domain; /* DO, NA, ... */
u16 instance; /* ff: no instance required */
};
#ifdef ESIF_ATTR_USER
typedef struct esif_primitive_tuple EsifPrimitiveTuple, *EsifPrimitiveTuplePtr,
**EsifPrimitiveTuplePtrLoction;
#endif
struct esif_lp_primitive {
struct esif_primitive_tuple tuple; /* PRIMITIVE Tuple */
enum esif_primitive_opcode opcode; /* PRIMITIVE Operation Type */
u8 action_count; /* Number Of Actions For This Primitive */
struct esif_data *context_ptr; /* Context For Primitive e.g. VAR */
};
#pragma pack(pop)
#ifdef __cplusplus
extern "C" {
#endif
struct esif_ipc *esif_execute_ipc_primitive(struct esif_ipc *ipc_ptr);
struct esif_lp;
struct esif_ipc_primitive;
enum esif_rc esif_execute_primitive(struct esif_lp *lp_ptr,
const struct esif_primitive_tuple *tuple_ptr,
const struct esif_data *req_data_ptr,
struct esif_data *rsp_data_ptr,
const u16 *action_index_ptr);
/*
* Simple helper function to execute a primitive that takes no special
* parameters.
*/
enum esif_rc esif_get_simple_primitive(struct esif_lp *lp_ptr,
u16 id,
u16 domain,
u16 instance,
enum esif_data_type esif_type,
void *buffer_ptr,
u32 buffer_size);
#ifdef __cplusplus
}
#endif
#endif /* _ESIF_LF_PRIMITIVE_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,371 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#include "esif_queue.h"
#ifdef ESIF_ATTR_OS_WINDOWS
/*
*
* The Windows banned-API check header must be included after all other headers,
* or issues can be identified
* against Windows SDK/DDK included headers which we have no control over.
*
*/
#define _SDL_BANNED_RECOMMENDED
#include "win\banned.h"
#endif
#ifdef ESIF_ATTR_KERNEL
#define INIT_DEBUG 0
#define Q_DEBUG 1
#define PULL_DEBUG 2
#define SEM_DEBUG 3
#define ESIF_TRACE_DYN_INIT(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_QUEUE, INIT_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_Q(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_QUEUE, Q_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_PULL(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_QUEUE, PULL_DEBUG, format, ##__VA_ARGS__)
#define ESIF_TRACE_DYN_SEM(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_QUEUE, SEM_DEBUG, format, ##__VA_ARGS__)
#else /* ESIF_ATTR_KERNEL */
/*
* TODO: User mode does not currently use the queue code.
* Need to update when user mode unified debug infrastructre
* is in place.
*/
#define ESIF_TRACE_DYN_INIT NO_ESIF_DEBUG
#define ESIF_TRACE_DYN_Q NO_ESIF_DEBUG
#define ESIF_TRACE_DYN_PULL NO_ESIF_DEBUG
#define ESIF_TRACE_DYN_SEM NO_ESIF_DEBUG
#endif /* ESIF_ATTR_USER */
/* Queue Node */
struct esif_queue_node {
struct esif_queue_node *next_ptr; /* Next Item In The Queue */
struct esif_ipc *ipc_ptr; /* Queued IPC/Event */
};
/* Queue Create */
struct esif_queue_instance *esif_queue_create(
u32 depth,
char *name_ptr
)
{
struct esif_queue_instance *queue_ptr = (struct esif_queue_instance *)
esif_ccb_malloc(sizeof(*queue_ptr));
if (NULL == queue_ptr)
return NULL;
esif_ccb_lock_init(&queue_ptr->lock);
esif_ccb_sem_init(&queue_ptr->semaphore);
queue_ptr->max_size = depth;
queue_ptr->us_timeout = 1000000;/* Second */
queue_ptr->name_ptr = name_ptr;
ESIF_TRACE_DYN_Q("%s: Create %s Queue %p depth = %d\n",
ESIF_FUNC,
name_ptr,
queue_ptr,
depth);
return queue_ptr;
}
/* Queue Destroy */
void esif_queue_destroy(struct esif_queue_instance *queue_ptr)
{
struct esif_queue_node *current_ptr = queue_ptr->head_ptr;
esif_ccb_write_lock(&queue_ptr->lock);
for (current_ptr = queue_ptr->head_ptr;
current_ptr != queue_ptr->tail_ptr;
current_ptr = queue_ptr->head_ptr) {
queue_ptr->head_ptr = current_ptr->next_ptr;
ESIF_TRACE_DYN_Q("%s: %s Queue Clean ipc %p\n",
ESIF_FUNC, queue_ptr->name_ptr, current_ptr);
esif_ipc_free(current_ptr->ipc_ptr);
esif_ccb_mempool_free(ESIF_MEMPOOL_TYPE_QUEUE, current_ptr);
}
if (current_ptr != NULL) {
ESIF_TRACE_DYN_Q("%s: %s Queue Clean ipc %p\n",
ESIF_FUNC, queue_ptr->name_ptr, current_ptr);
esif_ipc_free(current_ptr->ipc_ptr);
esif_ccb_mempool_free(ESIF_MEMPOOL_TYPE_QUEUE, current_ptr);
}
esif_ccb_write_unlock(&queue_ptr->lock);
esif_ccb_lock_uninit(&queue->lock);
esif_ccb_sem_uninit(&queue->semaphore);
ESIF_TRACE_DYN_Q("%s: %s Destroy Queue %p\n",
ESIF_FUNC,
queue_ptr->name_ptr,
queue_ptr);
esif_ccb_free(queue_ptr);
}
/* Queue Config */
enum esif_rc esif_queue_config(
struct esif_queue_instance *queue_ptr,
u32 us_timeout,
u32 max_size
)
{
esif_ccb_write_lock(&queue_ptr->lock);
queue_ptr->us_timeout = us_timeout;
queue_ptr->max_size = max_size;
esif_ccb_write_unlock(&queue_ptr->lock);
return ESIF_OK;
}
/* Queue Push (Puts in back of linked list)*/
enum esif_rc esif_queue_push(
struct esif_queue_instance *queue_ptr,
struct esif_ipc *ipc_ptr
)
{
struct esif_queue_node *node_ptr = NULL;
if (queue_ptr->current_size >= queue_ptr->max_size) {
ESIF_TRACE_DYN_Q("%s: No queue space, max size = %d\n",
ESIF_FUNC,
queue_ptr->max_size);
return ESIF_E_NO_MEMORY;
}
node_ptr = esif_ccb_mempool_zalloc(ESIF_MEMPOOL_TYPE_QUEUE);
if (NULL == node_ptr)
return ESIF_E_NO_MEMORY;
node_ptr->ipc_ptr = ipc_ptr;
esif_ccb_write_lock(&queue_ptr->lock);
node_ptr->next_ptr = NULL;
if (NULL == queue_ptr->head_ptr) {
queue_ptr->head_ptr = node_ptr;
queue_ptr->tail_ptr = node_ptr;
} else {
queue_ptr->tail_ptr->next_ptr = node_ptr;
queue_ptr->tail_ptr = node_ptr;
}
queue_ptr->current_size++;
esif_ccb_write_unlock(&queue_ptr->lock);
/* Wakeup */
ESIF_TRACE_DYN_Q("%s: %s Queue Push q %p ipc %p SEM UP\n",
ESIF_FUNC, queue_ptr->name_ptr, queue_ptr, ipc_ptr);
esif_ccb_sem_up(&queue_ptr->semaphore);
return ESIF_OK;
}
/* Queue Push (Put at front of linked list, used for returning item to queue) */
enum esif_rc esif_queue_requeue(
struct esif_queue_instance *queue_ptr,
struct esif_ipc *ipc_ptr
)
{
struct esif_queue_node *node_ptr = NULL;
if (queue_ptr->current_size >= queue_ptr->max_size) {
ESIF_TRACE_DYN_Q("%s: No queue space, max size = %d\n",
ESIF_FUNC,
queue_ptr->max_size);
return ESIF_E_NO_MEMORY;
}
node_ptr = esif_ccb_mempool_zalloc(ESIF_MEMPOOL_TYPE_QUEUE);
if (NULL == node_ptr)
return ESIF_E_NO_MEMORY;
node_ptr->ipc_ptr = ipc_ptr;
esif_ccb_write_lock(&queue_ptr->lock);
node_ptr->next_ptr = NULL;
if (NULL == queue_ptr->head_ptr) {
queue_ptr->head_ptr = node_ptr;
queue_ptr->tail_ptr = node_ptr;
} else {
node_ptr->next_ptr = queue_ptr->head_ptr;
queue_ptr->head_ptr = node_ptr;
}
queue_ptr->current_size++;
esif_ccb_write_unlock(&queue_ptr->lock);
/* Wakeup */
ESIF_TRACE_DYN_Q("%s: %s Queue Push q %p ipc %p SEM UP\n",
ESIF_FUNC, queue_ptr->name_ptr, queue_ptr, ipc_ptr);
esif_ccb_sem_up(&queue_ptr->semaphore);
return ESIF_OK;
}
/* Queue Pull */
struct esif_ipc *esif_queue_pull(struct esif_queue_instance *queue_ptr)
{
struct esif_queue_node *node_ptr = NULL;
struct esif_ipc *ipc_ptr = NULL;
ESIF_TRACE_DYN_SEM("%s: semophore timeout %d\n",
ESIF_FUNC,
queue_ptr->us_timeout);
/* Wait Forever */
if (0 == queue_ptr->us_timeout) {
esif_ccb_sem_down(&queue_ptr->semaphore);
/* Wait For N Usecs and If No Queue Entry Availabe Return False */
} else if (esif_ccb_sem_try_down(&queue_ptr->semaphore,
queue_ptr->us_timeout) != 0) {
return NULL;
}
esif_ccb_write_lock(&queue_ptr->lock);
if (NULL == queue_ptr->head_ptr) {
esif_ccb_write_unlock(&queue_ptr->lock);
return NULL; /* Could happen if a flush occurs after semaphore*/
}
node_ptr = queue_ptr->head_ptr;
ipc_ptr = node_ptr->ipc_ptr;
queue_ptr->head_ptr = node_ptr->next_ptr;
if (NULL == queue_ptr->head_ptr)
queue_ptr->tail_ptr = NULL;
esif_ccb_write_unlock(&queue_ptr->lock);
queue_ptr->current_size--;
esif_ccb_mempool_free(ESIF_MEMPOOL_TYPE_QUEUE, node_ptr);
ESIF_TRACE_DYN_Q("%s: %s Queue Pull q %p ipc %p\n",
ESIF_FUNC, queue_ptr->name_ptr, queue_ptr, ipc_ptr);
return ipc_ptr;
}
/* Queue Size */
u32 esif_queue_size(struct esif_queue_instance *queue_ptr)
{
ESIF_TRACE_DYN_PULL("%s: %s Queue Size %d\n",
ESIF_FUNC,
queue_ptr->name_ptr,
queue_ptr->current_size);
return queue_ptr->current_size;
}
/* Queue Flush */
void esif_queue_flush(struct esif_queue_instance *queue_ptr)
{
struct esif_queue_node *node_ptr = NULL;
esif_ccb_write_lock(&queue_ptr->lock);
node_ptr = queue_ptr->head_ptr;
while (node_ptr != NULL) {
queue_ptr->head_ptr = node_ptr->next_ptr;
esif_ipc_free(node_ptr->ipc_ptr);
esif_ccb_mempool_free(ESIF_MEMPOOL_TYPE_QUEUE, node_ptr);
node_ptr = queue_ptr->head_ptr;
}
queue_ptr->current_size = 0;
queue_ptr->head_ptr = NULL;
queue_ptr->tail_ptr = NULL;
esif_ccb_write_unlock(&queue_ptr->lock);
}
/* Init */
enum esif_rc esif_queue_init(void)
{
struct esif_ccb_mempool *mempool_ptr = NULL;
ESIF_TRACE_DYN_INIT("%s: Initialize Queue Manager\n", ESIF_FUNC);
mempool_ptr =
esif_ccb_mempool_create(ESIF_MEMPOOL_TYPE_QUEUE,
ESIF_MEMPOOL_FW_QUEUE,
sizeof(struct esif_queue_node));
if (NULL == mempool_ptr)
return ESIF_E_NO_MEMORY;
return ESIF_OK;
}
/* Exit */
void esif_queue_exit(void)
{
ESIF_TRACE_DYN_INIT("%s: Exit Queue Manager\n", ESIF_FUNC);
}
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,100 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_QUEUE_H_
#define _ESIF_QUEUE_H_
#include "esif_ipc.h"
/* Queue Instance */
struct esif_queue_instance {
u32 us_timeout; /* Timeout in Microseconds */
u32 max_size; /* Maximum allowable queue size in items */
u32 current_size; /* Current queeue size in items */
esif_ccb_lock_t lock; /* Lock */
esif_ccb_sem_t semaphore; /* To allow blocking if queue is empty */
struct esif_queue_node *head_ptr; /* First event or NULL if queue Is empty */
struct esif_queue_node *tail_ptr; /* Last event or NULL if queue Is empty */
char *name_ptr; /* Queue Name */
};
#ifdef __cplusplus
extern "C" {
#endif
struct esif_queue_instance *esif_queue_create (u32 depth, char *name_ptr);
void esif_queue_destroy (struct esif_queue_instance *queue_ptr);
enum esif_rc esif_queue_push (struct esif_queue_instance *queue_ptr,
struct esif_ipc *ipc_ptr);
enum esif_rc esif_queue_requeue (struct esif_queue_instance *queue_ptr,
struct esif_ipc *ipc_ptr);
struct esif_ipc *esif_queue_pull (struct esif_queue_instance *queue_ptr);
u32 esif_queue_size (struct esif_queue_instance *queue_ptr);
/* Init / Exit */
enum esif_rc esif_queue_init (void);
void esif_queue_exit (void);
#ifdef __cplusplus
}
#endif
#endif /* _ESIF_QUEUE_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,287 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_RC_H_
#define _ESIF_RC_H_
#ifdef ESIF_ATTR_USER
#include "esif.h"
#endif
/* Return Code ... may there be many be verbose in errror reporting */
enum esif_rc {
ESIF_OK = 0, /* Success */
/*
**********************************************************************
* INFORMATIONAL
**********************************************************************
*/
ESIF_I_ACPI_TRIP_POINT_NOT_PRESENT = 100, /* Information Requested Trip Point Not Present */
ESIF_I_ACPI_OBJECT_NOT_PRESENT, /* Optional Object Such As _STR */
ESIF_I_AGAIN, /* Come Back And Try Again Later */
ESIF_I_MSR_AFFINITY, /* Not All MSR Affinities Operaional/Supported */
/*
**********************************************************************
* ERROR
**********************************************************************
*/
ESIF_E_NOT_IMPLEMENTED = 1000, /* TBD / Not Implemented Yet */
ESIF_E_NO_LOWER_FRAMEWORK, /* No Lower Framework / Kernel Module */
ESIF_E_NOT_SUPPORTED, /* Operation Not Supported By Object */
ESIF_E_UNSPECIFIED, /* Catchall Error Code*/
ESIF_E_INVALID_HANDLE, /* INVALID Handle Provided */
/* ACPI */
ESIF_E_NO_ACPI_SUPPORT = 1100, /* No ACPI Platform Support */
ESIF_E_NO_ACPII_SUPPORT, /* No Intel ACPI Platform Support */
ESIF_E_NO_ACPI5_SUPPORT, /* No ACPI5 Support */
ESIF_E_ACPI_RESULT_TYPE, /* Error Reading ACPI Data */
ESIF_E_ACPI_REQUEST_TYPE, /* Error Reading ACPI Data */
ESIF_E_ACPI_EVAL_FAILURE, /* ACPI Evaluation Failure */
ESIF_E_ACPI_OBJECT_NOT_FOUND, /* Requested ACPI Object Not Found */
ESIF_E_UNSUPPORTED_ACPI_NOTIFY_EVENT, /* ACPI Notify Event is Not Supported/Recognized */
/* Action */
ESIF_E_ACTION_NOT_IMPLEMENTED = 1200, /* Unsupported Action*/
ESIF_E_OVERFLOWED_RESULT_TYPE, /* ESIF Data Buffer Overflow Would've Occured */
ESIF_E_UNSUPPORTED_ACTION_TYPE, /* Undefined Primitive Action Type */
ESIF_E_UNSUPPORTED_REQUEST_DATA_TYPE, /* Unsupported Req Data Type */
ESIF_E_UNSUPPORTED_RESULT_DATA_TYPE, /* Unsupported Result Data Type */
ESIF_E_INVALID_REQUEST_TYPE, /* Request Type Invalid */
ESIF_E_XFORM_NOT_AVAILABLE, /* Xform Is Unavailable */
/* Buffer */
ESIF_E_NEED_LARGER_BUFFER = 1300, /* Response Data Size Will Contain Needed Buf_Size */
ESIF_E_NEED_BINARY_BUFFER, /* Action Response Data Must Be Binary */
/* Callback */
ESIF_E_CALLBACK_IS_NULL = 1400, /* Callback Function Pointer Is NULL */
/* Command */
ESIF_E_COMMAND_DATA_INVALID = 1500, /* Command Data Invalid/ Short */
/* CPC */
ESIF_E_CPC_SHORT = 1600,/* CPC Data To Short */
ESIF_E_CPC_SIGNATURE, /* CPC Signature Failure Must Be %CPC */
/* IPC */
ESIF_E_IPC_DATA_INVALID = 1700, /* IPC Data Invalid / Short For Type */
/* MEMORY */
ESIF_E_NO_MEMORY = 1800, /* Memory Allocation Error */
ESIF_E_NO_CREATE, /* OBJECT Creation Failure */
/* MMIO */
ESIF_E_NO_MMIO_SUPPORT = 1900, /* No MMIO support in this device */
/* MBI */
ESIF_E_NO_MBI_SUPPORT = 2000, /* No MBI support in this device */
/* MSR */
ESIF_E_MSR_IO_FAILURE = 2100, /* MSR Read or Write Error*/
ESIF_E_MSR_MULTI_VALUES, /* Values Are Different On Different CPUs Such That They Cannot Be Presented By UINT */
/* Participant */
ESIF_E_PARTICIPANT_NOT_FOUND = 2200, /* Participant Not Found */
/* Parameter */
ESIF_E_PARAMETER_IS_NULL = 2300, /* Parameter Is NULL */
ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS, /* Parameter Is Out Of Bounds */
/* PRIMITIVE */
ESIF_E_NULL_PRIMITIVE = 2400, /* Null Primitive Received During Loookup */
ESIF_E_NEED_DSP, /* DSP Not Loaded */
ESIF_E_PRIMITIVE_ACTION_FAILURE, /* Primitive Execution Failure */
ESIF_E_PRIMITIVE_DST_UNAVAIL, /* Primitive Destination Unavailable */
ESIF_E_PRIMITIVE_NOT_FOUND_IN_DSP, /* Primitive Not In Current DSP */
ESIF_E_OPCODE_NOT_IMPLEMENTED, /* Primitive Opcode Not Implemented */
/* Temperatue Conversion */
ESIF_E_UNSUPPORTED_REQUEST_TEMP_TYPE = 2500, /* Unsupported Req Temp Type */
ESIF_E_UNSUPPORTED_RESULT_TEMP_TYPE, /* Unsupported Result/Resp
Temp Type */
/* TIMER */
ESIF_E_TIMEOUT = 2600, /* Timeout*/
/* TABLE */
ESIF_E_NOT_TABLE = 2700, /* TABLE Header type */
/* Power Conversion */
ESIF_E_UNSUPPORTED_REQUEST_POWER_TYPE = 2800, /* Unsupported Request Power Type */
ESIF_E_UNSUPPORTED_RESULT_POWER_TYPE, /* Unsupported Result/Response Power Type */
/* Xform Algorithm */
ESIF_E_NEED_ALGORITHM = 2900, /* Unspecified Xform Algorithm in DSP */
ESIF_E_UNSUPPORTED_ALGORITHM, /* Algorithm Is Not Supported */
/* Repository */
ESIF_E_NOT_FOUND = 3000, /* Item Not Found */
ESIF_E_READONLY, /* Item is Read-Only */
ESIF_E_IO_ERROR, /* File I/O Error */
ESIF_E_IO_OPEN_FAILED, /* File Open/Create Failed */
ESIF_E_IO_DELETE_FAILED, /* File Delete Failed */
/* Web Server */
ESIF_E_WS_DISC = 3100, /* WS client disconnected */
};
/* Convert Return Code To A String */
static ESIF_INLINE char
*esif_rc_str(enum esif_rc type)
{
/* TODO: Lifu to fix */
#define ESIF_CREATE_RC(rc) case rc: \
str = (esif_string) #rc; break;
esif_string str = (esif_string)ESIF_NOT_AVAILABLE;
switch (type) {
ESIF_CREATE_RC(ESIF_OK)
ESIF_CREATE_RC(ESIF_I_ACPI_TRIP_POINT_NOT_PRESENT)
ESIF_CREATE_RC(ESIF_I_ACPI_OBJECT_NOT_PRESENT)
ESIF_CREATE_RC(ESIF_I_AGAIN)
ESIF_CREATE_RC(ESIF_I_MSR_AFFINITY)
ESIF_CREATE_RC(ESIF_E_NOT_IMPLEMENTED)
ESIF_CREATE_RC(ESIF_E_NO_LOWER_FRAMEWORK)
ESIF_CREATE_RC(ESIF_E_NOT_SUPPORTED)
ESIF_CREATE_RC(ESIF_E_UNSPECIFIED)
ESIF_CREATE_RC(ESIF_E_INVALID_HANDLE)
ESIF_CREATE_RC(ESIF_E_NO_ACPI_SUPPORT)
ESIF_CREATE_RC(ESIF_E_NO_ACPII_SUPPORT)
ESIF_CREATE_RC(ESIF_E_NO_ACPI5_SUPPORT)
ESIF_CREATE_RC(ESIF_E_ACPI_RESULT_TYPE)
ESIF_CREATE_RC(ESIF_E_ACPI_REQUEST_TYPE)
ESIF_CREATE_RC(ESIF_E_ACPI_EVAL_FAILURE)
ESIF_CREATE_RC(ESIF_E_ACPI_OBJECT_NOT_FOUND)
ESIF_CREATE_RC(ESIF_E_UNSUPPORTED_ACPI_NOTIFY_EVENT)
ESIF_CREATE_RC(ESIF_E_ACTION_NOT_IMPLEMENTED)
ESIF_CREATE_RC(ESIF_E_OVERFLOWED_RESULT_TYPE)
ESIF_CREATE_RC(ESIF_E_UNSUPPORTED_ACTION_TYPE)
ESIF_CREATE_RC(ESIF_E_UNSUPPORTED_REQUEST_DATA_TYPE)
ESIF_CREATE_RC(ESIF_E_UNSUPPORTED_RESULT_DATA_TYPE)
ESIF_CREATE_RC(ESIF_E_INVALID_REQUEST_TYPE)
ESIF_CREATE_RC(ESIF_E_XFORM_NOT_AVAILABLE)
ESIF_CREATE_RC(ESIF_E_NEED_LARGER_BUFFER)
ESIF_CREATE_RC(ESIF_E_NEED_BINARY_BUFFER)
ESIF_CREATE_RC(ESIF_E_CALLBACK_IS_NULL)
ESIF_CREATE_RC(ESIF_E_COMMAND_DATA_INVALID)
ESIF_CREATE_RC(ESIF_E_CPC_SHORT)
ESIF_CREATE_RC(ESIF_E_CPC_SIGNATURE)
ESIF_CREATE_RC(ESIF_E_IPC_DATA_INVALID)
ESIF_CREATE_RC(ESIF_E_NO_MEMORY)
ESIF_CREATE_RC(ESIF_E_NO_CREATE)
ESIF_CREATE_RC(ESIF_E_NO_MMIO_SUPPORT)
ESIF_CREATE_RC(ESIF_E_NO_MBI_SUPPORT)
ESIF_CREATE_RC(ESIF_E_MSR_IO_FAILURE)
ESIF_CREATE_RC(ESIF_E_MSR_MULTI_VALUES)
ESIF_CREATE_RC(ESIF_E_PARTICIPANT_NOT_FOUND)
ESIF_CREATE_RC(ESIF_E_PARAMETER_IS_NULL)
ESIF_CREATE_RC(ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS)
ESIF_CREATE_RC(ESIF_E_NULL_PRIMITIVE)
ESIF_CREATE_RC(ESIF_E_NEED_DSP)
ESIF_CREATE_RC(ESIF_E_PRIMITIVE_ACTION_FAILURE)
ESIF_CREATE_RC(ESIF_E_PRIMITIVE_DST_UNAVAIL)
ESIF_CREATE_RC(ESIF_E_PRIMITIVE_NOT_FOUND_IN_DSP)
ESIF_CREATE_RC(ESIF_E_OPCODE_NOT_IMPLEMENTED)
ESIF_CREATE_RC(ESIF_E_UNSUPPORTED_REQUEST_TEMP_TYPE)
ESIF_CREATE_RC(ESIF_E_UNSUPPORTED_RESULT_TEMP_TYPE)
ESIF_CREATE_RC(ESIF_E_TIMEOUT)
ESIF_CREATE_RC(ESIF_E_NOT_TABLE)
ESIF_CREATE_RC(ESIF_E_UNSUPPORTED_REQUEST_POWER_TYPE)
ESIF_CREATE_RC(ESIF_E_UNSUPPORTED_RESULT_POWER_TYPE)
ESIF_CREATE_RC(ESIF_E_NEED_ALGORITHM)
ESIF_CREATE_RC(ESIF_E_UNSUPPORTED_ALGORITHM)
ESIF_CREATE_RC(ESIF_E_NOT_FOUND)
ESIF_CREATE_RC(ESIF_E_READONLY)
ESIF_CREATE_RC(ESIF_E_IO_ERROR)
ESIF_CREATE_RC(ESIF_E_IO_OPEN_FAILED)
ESIF_CREATE_RC(ESIF_E_IO_DELETE_FAILED)
ESIF_CREATE_RC(ESIF_E_WS_DISC)
}
return str;
}
#ifdef ESIF_ATTR_USER
typedef enum esif_rc eEsifError;
#endif
#endif /* _ESIF_RC_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

View File

@@ -0,0 +1,308 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_TEMP_H_
#define _ESIF_TEMP_H_
#define TEMP_DEBUG 13 /* Debug Module Level */
#ifdef ESIF_ATTR_KERNEL
#define ESIF_TRACE_DYN_TEMP(format, ...) \
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_ELF, TEMP_DEBUG, format, ##__VA_ARGS__)
#endif /* ESIF_ATTR_KERNEL */
#ifdef ESIF_ATTR_USER
/*
* TODO: User mode does not currently support this debug area.
* Need to update when user mode unified debug infrastructre
* is in place.
*/
#define ESIF_TRACE_DYN_TEMP NO_ESIF_DEBUG
#endif /* ESIF_ATTR_USER */
/* Termperature Unit Type */
enum esif_temperature_type {
ESIF_TEMP_K = 0, /* Kelvin */
ESIF_TEMP_DECIK, /* Deci Kelvin 300.0 K would be 3000 */
ESIF_TEMP_CENTIK, /* Centi Kelvin 300.0 K would be 30000 */
ESIF_TEMP_MILLIK, /* Milli Kelvin 300.0 K would be 300000 */
ESIF_TEMP_C, /* Celsius */
ESIF_TEMP_DECIC, /* Deci Celsisus 40.0 C would be 400 */
ESIF_TEMP_CENTIC, /* Centi Celsisus 40.0 C would be 4000 */
ESIF_TEMP_MILLIC, /* Milli Celsisus 40.0 C would be 40000 */
ESIF_TEMP_THERMISTOR, /* EC Thermistor */
};
/* Termperature Unit Type String */
static ESIF_INLINE esif_string esif_temperature_type_str(
enum esif_temperature_type type)
{
#define ESIF_CREATE_TEMP_TYPE(t, str) case t: str = #t; break;
esif_string str = ESIF_NOT_AVAILABLE;
switch (type) {
ESIF_CREATE_TEMP_TYPE(ESIF_TEMP_K, str)
ESIF_CREATE_TEMP_TYPE(ESIF_TEMP_DECIK, str)
ESIF_CREATE_TEMP_TYPE(ESIF_TEMP_CENTIK, str)
ESIF_CREATE_TEMP_TYPE(ESIF_TEMP_MILLIK, str)
ESIF_CREATE_TEMP_TYPE(ESIF_TEMP_C, str)
ESIF_CREATE_TEMP_TYPE(ESIF_TEMP_DECIC, str)
ESIF_CREATE_TEMP_TYPE(ESIF_TEMP_CENTIC, str)
ESIF_CREATE_TEMP_TYPE(ESIF_TEMP_MILLIC, str)
ESIF_CREATE_TEMP_TYPE(ESIF_TEMP_THERMISTOR, str)
}
return str;
}
/* Power Unit Description */
static ESIF_INLINE esif_string esif_temperature_type_desc(
enum esif_temperature_type type)
{
#define ESIF_CREATE_TEMP_UNIT_DESC(t, td, str) case t: str = td; break;
esif_string str = ESIF_NOT_AVAILABLE;
switch (type) {
ESIF_CREATE_TEMP_UNIT_DESC(ESIF_TEMP_K, "K", str)
ESIF_CREATE_TEMP_UNIT_DESC(ESIF_TEMP_DECIK, "DeciK", str)
ESIF_CREATE_TEMP_UNIT_DESC(ESIF_TEMP_CENTIK, "CentiK", str)
ESIF_CREATE_TEMP_UNIT_DESC(ESIF_TEMP_MILLIK, "MilliK", str)
ESIF_CREATE_TEMP_UNIT_DESC(ESIF_TEMP_C, "C", str)
ESIF_CREATE_TEMP_UNIT_DESC(ESIF_TEMP_DECIC, "DeciC", str)
ESIF_CREATE_TEMP_UNIT_DESC(ESIF_TEMP_CENTIC, "CentiC", str)
ESIF_CREATE_TEMP_UNIT_DESC(ESIF_TEMP_MILLIC, "MilliC", str)
ESIF_CREATE_TEMP_UNIT_DESC(ESIF_TEMP_THERMISTOR, "Thermistor", str)
}
return str;
}
/*
* Select Temperature Unit To Normalize Temperatures To.
*/
/* DPTF Wants Everything In Degrees C */
#define NORMALIZE_TEMP_TYPE ESIF_TEMP_C
/* Convert In Between Kelvin and Celsius */
#define DPTF_KELVIN_BASE 2732
/* Normalize Celisus temperature. */
static ESIF_INLINE int esif_convert_temp(
enum esif_temperature_type in,
enum esif_temperature_type out,
esif_temp_t *temp_ptr
)
{
esif_temp_t val = 0;
if (NULL == temp_ptr)
return ESIF_E_PARAMETER_IS_NULL;
val = *temp_ptr;
if (val == 0 || in == out)
return ESIF_OK;
/* Always Raise Up Input Value To Milli-C/K */
switch (in) {
case ESIF_TEMP_C:
case ESIF_TEMP_K:
val = *temp_ptr * 1000;
break;
case ESIF_TEMP_DECIC:
case ESIF_TEMP_DECIK:
val = *temp_ptr * 100;
break;
case ESIF_TEMP_CENTIC:
case ESIF_TEMP_CENTIK:
val = *temp_ptr * 10;
break;
case ESIF_TEMP_MILLIC:
case ESIF_TEMP_MILLIK:
break;
default:
return ESIF_E_UNSUPPORTED_REQUEST_TEMP_TYPE;
}
/* Add 5, 50 or 500 To Make It Round Up */
#define esif_temp_c2c(out, val) { \
switch (out) { \
case ESIF_TEMP_C: \
val = (val + 500) / 1000; \
break; \
case ESIF_TEMP_DECIC: \
val = (val + 50) / 100; \
break; \
case ESIF_TEMP_CENTIC: \
val = (val + 5) / 10; \
break; \
case ESIF_TEMP_MILLIC: \
default: \
break; \
} \
}
#define esif_temp_k2c(out, val) { \
switch (out) { \
case ESIF_TEMP_C: \
val = ((val - (DPTF_KELVIN_BASE * 100)) + 500) / 1000;\
break; \
case ESIF_TEMP_DECIC: \
val = ((val - (DPTF_KELVIN_BASE * 100)) + 50) / 100;\
break; \
case ESIF_TEMP_CENTIC: \
val = ((val - (DPTF_KELVIN_BASE * 100)) + 5) / 10;\
break; \
case ESIF_TEMP_MILLIC: \
val = (val - (DPTF_KELVIN_BASE * 100)); \
break; \
default: \
break; \
} \
}
#define esif_temp_c2k(out, val) { \
switch (out) { \
case ESIF_TEMP_K: \
val = ((val + (DPTF_KELVIN_BASE * 100)) + 500) / 1000;\
break; \
case ESIF_TEMP_DECIK: \
val = ((val + (DPTF_KELVIN_BASE * 100)) + 50) / 100;\
break; \
case ESIF_TEMP_CENTIK: \
val = ((val + (DPTF_KELVIN_BASE * 100)) + 5) / 10;\
break; \
case ESIF_TEMP_MILLIK: \
val = (val + (DPTF_KELVIN_BASE * 100)); \
break; \
default: \
break; \
} \
}
#define esif_temp_k2k(out, val) { \
switch (out) { \
case ESIF_TEMP_K: \
val = (val + 500) / 1000; \
break; \
case ESIF_TEMP_DECIK: \
val = (val + 50) / 100; \
break; \
case ESIF_TEMP_CENTIK: \
val = (val + 5) / 10; \
break; \
case ESIF_TEMP_MILLIK: \
default: \
break; \
} \
}
/* Normalize To Output Type */
switch (out) {
case ESIF_TEMP_C:
case ESIF_TEMP_DECIC:
case ESIF_TEMP_CENTIC:
case ESIF_TEMP_MILLIC:
switch (in) {
case ESIF_TEMP_K:
case ESIF_TEMP_DECIK:
case ESIF_TEMP_CENTIK:
case ESIF_TEMP_MILLIK:
esif_temp_k2c(out, val);
break;
default:
esif_temp_c2c(out, val);
}
break;
case ESIF_TEMP_K:
case ESIF_TEMP_DECIK:
case ESIF_TEMP_CENTIK:
case ESIF_TEMP_MILLIK:
switch (in) {
case ESIF_TEMP_K:
case ESIF_TEMP_DECIK:
case ESIF_TEMP_CENTIK:
case ESIF_TEMP_MILLIK:
esif_temp_k2k(out, val);
break;
default:
esif_temp_c2k(out, val);
}
break;
default:
return ESIF_E_UNSUPPORTED_REQUEST_TEMP_TYPE;
}
ESIF_TRACE_DYN_TEMP("IN %6u %-6s, OUT %6u %-6s\n",
*temp_ptr,
esif_temperature_type_desc(in),
val,
esif_temperature_type_desc(out));
*temp_ptr = val;
return ESIF_OK;
}
#endif /* _ESIF_TEMP_H_ */
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

View File

@@ -0,0 +1,83 @@
/*******************************************************************************
** This file is provided under a dual BSD/GPLv2 license. When using or
** redistributing this file, you may do so under either license.
**
** GPL LICENSE SUMMARY
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** This program is free software; you can redistribute it and/or modify it under
** the terms of version 2 of the GNU General Public License as published by the
** Free Software Foundation.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
** details.
**
** You should have received a copy of the GNU General Public License along with
** this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
** The full GNU General Public License is included in this distribution in the
** file called LICENSE.GPL.
**
** BSD LICENSE
**
** Copyright (c) 2013 Intel Corporation All Rights Reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice, this
** list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** * Neither the name of Intel Corporation nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*******************************************************************************/
#ifndef _ESIF_VERSION_H_
#define _ESIF_VERSION_H_
#define STR(arg) #arg
#define STR2(arg) STR(##arg)
#define EXPAND_TOSTR(arg) STR(arg)
#define ESIF_VERSION_MAJOR 8
#define ESIF_VERSION_MINOR 0
#define ESIF_VERSION_HOTFIX 10001
#define ESIF_VERSION_BUILD 0
/* Build system will should set to 0 */
#define ESIF_SKU_TYPE 0
#if ESIF_SKU_TYPE == 0
#define ESIF_VERSION EXPAND_TOSTR( \
ESIF_VERSION_MAJOR.ESIF_VERSION_MINOR.ESIF_VERSION_HOTFIX.ESIF_VERSION_BUILD)
#else
/* X denotes development */
#define ESIF_VERSION EXPAND_TOSTR( \
X.ESIF_VERSION_MAJOR.ESIF_VERSION_MINOR.ESIF_VERSION_HOTFIX.ESIF_VERSION_BUILD)
#endif
#endif /* _ESIF_VERSION_H_ */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/