diff --git a/ec/test-cli/README.md b/ec/test-cli/README.md index faa2fad..400a815 100644 --- a/ec/test-cli/README.md +++ b/ec/test-cli/README.md @@ -16,7 +16,7 @@ For Windows on ARM (cross-compile): cargo build-win --release ``` -Note: to use the `local` source on Windows, you must have the `ectest.sys` KMDF driver built/installed and the required ACPI entries/device instance present. See [test-win/README.md](../test-win/README.md) for the Windows driver/setup requirements. +Note: to use the `local` source on Windows, you must have the `ectest.sys` KMDF driver built/installed and the required ACPI entries/device instance present. The driver lives in [odp-windows-drivers](https://github.com/OpenDevicePartnership/odp-windows-drivers) (`drivers/acpi`); see [test-win/README.md](../test-win/README.md) for the user-mode setup requirements. ## Usage diff --git a/ec/test-lib/src/acpi.rs b/ec/test-lib/src/acpi.rs index 3b52bdf..8e27a07 100644 --- a/ec/test-lib/src/acpi.rs +++ b/ec/test-lib/src/acpi.rs @@ -13,7 +13,7 @@ use windows::Win32::Foundation::*; use windows::Win32::System::IO::*; use windows::core::{GUID, PCWSTR}; -// GUID defined in the KMDF INX file for ectest.sys +// GUID defined in the ectest.sys KMDF driver (odp-windows-drivers, drivers/acpi) // {5362ad97-ddfe-429d-9305-31c0ad27880a} const GUID_DEVCLASS_ECTEST: GUID = GUID::from_values( 0x5362ad97, diff --git a/ec/test-tui/.gitignore b/ec/test-tui/.gitignore index 0e4fe5f..da5c022 100644 --- a/ec/test-tui/.gitignore +++ b/ec/test-tui/.gitignore @@ -4,9 +4,7 @@ /.vs /exe/.vs/ectest_app -/kmdf/.vs/ectest_kmdf /exe/ARM64 /lib/ARM64 /lib/eclib/ARM64 -/kmdf/ARM64 /rust/target diff --git a/ec/test-tui/README.md b/ec/test-tui/README.md index 775a785..e2ab500 100644 --- a/ec/test-tui/README.md +++ b/ec/test-tui/README.md @@ -15,7 +15,7 @@ For Windows on ARM (cross-compile): cargo build-win --release ``` -Note: to use the `local` source on Windows, you must have the `ectest.sys` KMDF driver built/installed and the required ACPI entries/device instance present. See [test-win/README.md](../test-win/README.md) for the Windows driver/setup requirements. +Note: to use the `local` source on Windows, you must have the `ectest.sys` KMDF driver built/installed and the required ACPI entries/device instance present. The driver lives in [odp-windows-drivers](https://github.com/OpenDevicePartnership/odp-windows-drivers) (`drivers/acpi`); see [test-win/README.md](../test-win/README.md) for the user-mode setup requirements. ## Usage diff --git a/ec/test-win/README.md b/ec/test-win/README.md index 26dabca..bfcf93f 100644 --- a/ec/test-win/README.md +++ b/ec/test-win/README.md @@ -1,13 +1,14 @@ # ec-test-win ## Overview -Windows native components for testing EC interfaces via ACPI. Includes a user-mode library, CLI test application, and a kernel-mode driver. +Windows native components for testing EC interfaces via ACPI. Includes a user-mode library and CLI test application that talk to the `ectest.sys` KMDF driver. + +> The `ectest.sys` KMDF driver now lives in the [odp-windows-drivers](https://github.com/OpenDevicePartnership/odp-windows-drivers) repository (`drivers/acpi`). Build and install it from there. The IOCTL/struct contract shared with the driver is kept here in `inc/ectest.h`. ## Structure ``` exe/ - User mode CLI (ectest.exe) to call and evaluate ACPI functions -inc/ - Shared header files between user-mode and kernel-mode components -kmdf/ - Kernel mode driver (ectest.sys) that evaluates ACPI methods +inc/ - Shared header files (incl. the IOCTL contract used to talk to ectest.sys) lib/ - User mode library (eclib) bridging user apps to the KMDF driver dep/ - External dependencies (WIL git submodule) ``` @@ -27,23 +28,20 @@ Compile eclib.lib and eclib.dll from `lib/`: msbuild /p:Configuration=Release /p:Platform=ARM64 ``` -Compile ectest.sys from `kmdf/`: -``` -msbuild /p:Configuration=Release /p:Platform=ARM64 -``` - Compile ectest.exe from `exe/`: ``` msbuild /p:Configuration=Release /p:Platform=ARM64 ``` +The `ectest.sys` KMDF driver is built from the [odp-windows-drivers](https://github.com/OpenDevicePartnership/odp-windows-drivers) repository (`drivers/acpi`). + ## Installing the Driver -After recompiling ACPI and booting your device, install the driver and run validation tests. +After recompiling ACPI and booting your device, install the driver and run validation tests. Build the `ectest.sys` driver from the [odp-windows-drivers](https://github.com/OpenDevicePartnership/odp-windows-drivers) repository (`drivers/acpi`). Copy the following files to a thumbdrive or location on the target: ``` ec\test-win\exe\arm64\Debug\ectest.exe -ec\test-win\kmdf\arm64\Debug\ectest_kmdf\* +\ectest_kmdf\* \Program Files\Windows Kits\10\Tools\10.0.26100.0\arm64\devcon.exe ``` diff --git a/ec/test-win/kmdf/device.c b/ec/test-win/kmdf/device.c deleted file mode 100644 index 213b45f..0000000 --- a/ec/test-win/kmdf/device.c +++ /dev/null @@ -1,117 +0,0 @@ -/*++ -Module Name: - device.c - Device handling events for example driver. - -Abstract: - This is a C version of a very simple sample driver that illustrates - how to use the driver framework and demonstrates best practices. ---*/ - -#include "driver.h" -#include "trace.h" -#include "device.tmh" - -#ifdef ALLOC_PRAGMA -#pragma alloc_text (PAGE, ECTestDeviceCreate) -#endif - - -NTSTATUS -ECTestDeviceCreate( - PWDFDEVICE_INIT DeviceInit - ) -/*++ - -Routine Description: - - Worker routine called to create a device and its software resources. - -Arguments: - - DeviceInit - Pointer to an opaque init structure. Memory for this - structure will be freed by the framework when the WdfDeviceCreate - succeeds. So don't access the structure after that point. - -Return Value: - - NTSTATUS - ---*/ -{ - WDF_OBJECT_ATTRIBUTES deviceAttributes; - PDEVICE_CONTEXT deviceContext; - WDFDEVICE device; - NTSTATUS status; - - PAGED_CODE(); - - WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT); - status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device); - - if (NT_SUCCESS(status)) { - // - // Get the device context and initialize it. DeviceContextGet is an - // inline function generated by WDF_DECLARE_CONTEXT_TYPE macro in the - // device.h header file. This function will do the type checking and return - // the device context. If you pass a wrong object handle - // it will return NULL and assert if run under framework verifier mode. - // - deviceContext = DeviceContextGet(device); - deviceContext->PendingRequest = NULL; - -#if defined(EC_TEST_NOTIFICATIONS) && defined(ENABLE_NOTIFICATION_SIMULATION) - deviceContext->Timer = NULL; -#endif - -#ifdef EC_TEST_NOTIFICATIONS - WDF_OBJECT_ATTRIBUTES attributes; - - WDF_OBJECT_ATTRIBUTES_INIT(&attributes); - attributes.ParentObject = device; - status = WdfWaitLockCreate(&attributes, &deviceContext->NotificationLock); - - if (NT_SUCCESS(status)) { -#endif // EC_TEST_NOTIFICATIONS - - // - // Create a device interface so that application can find and talk - // to us. - // - status = WdfDeviceCreateDeviceInterface( - device, - &GUID_DEVINTERFACE_ECTEST, - NULL // ReferenceString - ); - - if (NT_SUCCESS(status)) { - // - // Initialize the I/O Package and any Queues - // - status = ECTestQueueInitialize(device); - -#if defined(EC_TEST_NOTIFICATIONS) && defined(ENABLE_NOTIFICATION_SIMULATION) - WDF_OBJECT_ATTRIBUTES timerAttributes; - WDF_TIMER_CONFIG timerConfig; - // Initialize the timer configuration - WDF_TIMER_CONFIG_INIT_PERIODIC(&timerConfig, TimerCallback, 1000); // 1000 ms period - - // Set the timer attributes - WDF_OBJECT_ATTRIBUTES_INIT(&timerAttributes); - timerAttributes.ParentObject = device; - - // Create the timer - if (!NT_SUCCESS(WdfTimerCreate(&timerConfig, &timerAttributes, &deviceContext->Timer))) { - - // Ignore the failure, and allow the device to create successfully - Trace(TRACE_LEVEL_ERROR, TRACE_DEVICE,"WdfTimerCreate failed\n"); - deviceContext->Timer = NULL; - } -#endif - } -#ifdef EC_TEST_NOTIFICATIONS - } -#endif // EC_TEST_NOTIFICATIONS - } - - return status; -} diff --git a/ec/test-win/kmdf/device.h b/ec/test-win/kmdf/device.h deleted file mode 100644 index 042817c..0000000 --- a/ec/test-win/kmdf/device.h +++ /dev/null @@ -1,45 +0,0 @@ -/*++ -Module Name: - device.h - -Abstract: - This is a C version of a very simple sample driver that illustrates - how to use the driver framework and demonstrates best practices. ---*/ - -#include "public.h" - -#define EC_TEST_NOTIFICATIONS // Enable notification support -//#define ENABLE_NOTIFICATION_SIMULATION // Enable notification simulation - -// -// The device context performs the same job as -// a WDM device extension in the driver frameworks -// -typedef struct _DEVICE_CONTEXT -{ - WDFREQUEST PendingRequest; // Pending request for notification -#ifdef EC_TEST_NOTIFICATIONS - WDFWAITLOCK NotificationLock; // lock for notification -#endif -#if defined(EC_TEST_NOTIFICATIONS) && defined(ENABLE_NOTIFICATION_SIMULATION) - WDFTIMER Timer; // Timer for notification simulation -#endif -} DEVICE_CONTEXT, *PDEVICE_CONTEXT; - -// -// This macro will generate an inline function called DeviceContextGet -// which will be used to get a pointer to the device context memory -// in a type safe manner. -// -WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, DeviceContextGet) - -// -// Function to initialize the device and its callbacks -// -NTSTATUS ECTestDeviceCreate(PWDFDEVICE_INIT DeviceInit ); - -#if defined(EC_TEST_NOTIFICATIONS) && defined(ENABLE_NOTIFICATION_SIMULATION) -// Timer routine to simulate receiving the Notification at the driver. -VOID TimerCallback(WDFTIMER Timer); -#endif diff --git a/ec/test-win/kmdf/driver.c b/ec/test-win/kmdf/driver.c deleted file mode 100644 index c6a1e8e..0000000 --- a/ec/test-win/kmdf/driver.c +++ /dev/null @@ -1,133 +0,0 @@ -/*++ -Module Name: - driver.c - -Abstract: - This module contains the entry points and core routines for the WDF-based - function driver. It includes initialization logic in DriverEntry, device - creation in EvtDeviceAdd, and cleanup in DriverUnload. The driver also - integrates WPP tracing for diagnostics and logging. - -Environment: - Kernel-mode only - ---*/ - -#include "driver.h" -#include "trace.h" -#include "driver.tmh" - -#ifdef ALLOC_PRAGMA -#pragma alloc_text (INIT, DriverEntry) -#pragma alloc_text (PAGE, EvtDeviceAdd) -#endif - - -NTSTATUS -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ) -/*++ - -Routine Description: - DriverEntry initializes the driver and is the first routine called by the - system after the driver is loaded. DriverEntry specifies the other entry - points in the function driver, such as EvtDevice and DriverUnload. - -Parameters Description: - - DriverObject - represents the instance of the function driver that is loaded - into memory. DriverEntry must initialize members of DriverObject before it - returns to the caller. DriverObject is allocated by the system before the - driver is loaded, and it is released by the system after the system unloads - the function driver from memory. - - RegistryPath - represents the driver specific path in the Registry. - The function driver can use the path to store driver related data between - reboots. The path does not store hardware instance specific data. - -Return Value: - - STATUS_SUCCESS if successful, - STATUS_UNSUCCESSFUL otherwise. - ---*/ -{ - WDF_DRIVER_CONFIG config; - NTSTATUS status; - - // Initialize WPP tracing - WPP_INIT_TRACING(DriverObject, RegistryPath); - - WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAdd ); - - status = WdfDriverCreate(DriverObject, - RegistryPath, - WDF_NO_OBJECT_ATTRIBUTES, - &config, - WDF_NO_HANDLE); - if (!NT_SUCCESS(status)) { - Trace(TRACE_LEVEL_ERROR,TRACE_DRIVER,"Error: WdfDriverCreate failed 0x%x\n", status); - return status; - } - - return status; -} - -NTSTATUS -EvtDeviceAdd( - IN WDFDRIVER Driver, - IN PWDFDEVICE_INIT DeviceInit - ) -/*++ -Routine Description: - - EvtDeviceAdd is called by the framework in response to AddDevice - call from the PnP manager. We create and initialize a device object to - represent a new instance of the device. - -Arguments: - - Driver - Handle to a framework driver object created in DriverEntry - - DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure. - -Return Value: - - NTSTATUS - ---*/ -{ - NTSTATUS status; - - UNREFERENCED_PARAMETER(Driver); - PAGED_CODE(); - - Trace(TRACE_LEVEL_INFORMATION,TRACE_DRIVER,"Enter EvtDeviceAdd\n"); - status = ECTestDeviceCreate(DeviceInit); - - return status; -} - -VOID -DriverUnload( - _In_ PDRIVER_OBJECT DriverObject - ) -/*++ -Routine Description: - - DriverUnload is called when driver is unloaded to cleanup WPP tracing - -Arguments: - - Driver - Handle to a framework driver object created in DriverEntry - -Return Value: - ---*/ -{ - // Clean up WPP tracing - Trace(TRACE_LEVEL_INFORMATION,TRACE_DRIVER,"Enter DriverUnload\n"); - WPP_CLEANUP(DriverObject); -} \ No newline at end of file diff --git a/ec/test-win/kmdf/driver.h b/ec/test-win/kmdf/driver.h deleted file mode 100644 index 1d820ed..0000000 --- a/ec/test-win/kmdf/driver.h +++ /dev/null @@ -1,23 +0,0 @@ -/*++ -Module Name: - driver.h - -Abstract: - - This is a C version of a very simple driver that illustrates - how to use the driver framework and demonstrates best practices. ---*/ - -#define INITGUID - -#include -#include - -#include "device.h" -#include "queue.h" - -// -// WDFDRIVER Events -// -DRIVER_INITIALIZE DriverEntry; -EVT_WDF_DRIVER_DEVICE_ADD EvtDeviceAdd; diff --git a/ec/test-win/kmdf/ectest.inx b/ec/test-win/kmdf/ectest.inx deleted file mode 100644 index 9e6b6e1..0000000 Binary files a/ec/test-win/kmdf/ectest.inx and /dev/null differ diff --git a/ec/test-win/kmdf/ectest_kmdf.vcxproj b/ec/test-win/kmdf/ectest_kmdf.vcxproj deleted file mode 100644 index a1c9fec..0000000 --- a/ec/test-win/kmdf/ectest_kmdf.vcxproj +++ /dev/null @@ -1,182 +0,0 @@ - - - - - Debug - ARM64 - - - Release - ARM64 - - - Debug - x64 - - - Release - x64 - - - - {44FE3C21-35D7-4253-B15A-3E0F6AAB8B66} - $(MSBuildProjectName) - 1 - Debug - x64 - {315B8CBA-8105-439D-8F1A-F4291E25B6C6} - - - - Windows10 - False - Windows Driver - KMDF - WindowsKernelModeDriver10.0 - Driver - - - Windows10 - False - Windows Driver - KMDF - WindowsKernelModeDriver10.0 - Driver - - - Windows10 - True - Windows Driver - KMDF - WindowsKernelModeDriver10.0 - Driver - - - Windows10 - True - Windows Driver - KMDF - WindowsKernelModeDriver10.0 - Driver - - - - $(IntDir) - - - - - - - - - - - - - - - - ectest - - - ectest - - - ectest - - - ectest - - - - %(AdditionalIncludeDirectories);..\..\exe - - - %(AdditionalIncludeDirectories);..\..\exe - - - - - %(AdditionalIncludeDirectories);..\..\exe - - - sha256 - - - - - %(AdditionalIncludeDirectories);..\..\exe - - - %(AdditionalIncludeDirectories);..\..\exe - - - - - %(AdditionalIncludeDirectories);..\..\exe - - - sha256 - - - - - %(AdditionalIncludeDirectories);..\..\exe - - - %(AdditionalIncludeDirectories);..\..\exe - - - - - %(AdditionalIncludeDirectories);..\..\exe - - - sha256 - - - - - %(AdditionalIncludeDirectories);..\..\exe - - - %(AdditionalIncludeDirectories);..\..\exe - - - - - %(AdditionalIncludeDirectories);..\..\exe - - - sha256 - - - - - true - trace.h - - - true - trace.h - - - true - trace.h - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ec/test-win/kmdf/ffa.h b/ec/test-win/kmdf/ffa.h deleted file mode 100644 index 004a51e..0000000 --- a/ec/test-win/kmdf/ffa.h +++ /dev/null @@ -1,364 +0,0 @@ -/*++ - -Copyright (c) Microsoft Corporation. All rights reserved. - -Module Name: - - ffa.h - -Abstract: - - This module contains interface definitions and function prototypes exposed - by the HAL's FF-A subcomponent. - -Author: - - Kun Qin (kunqin) 10-Sep-2024 - ---*/ - -#pragma once - -// -// -------------------------------------------------------- Macro Definitions -// - -// -// FF-A notification macros -// - -// -// Maximum number of FF-A notifications that can be enabled in a single -// FF-A call (constrained by the number of available SMC registers available) to -// the notification service. If caller desires to enable more notifications, it -// woudl need to break the enablement into multiple calls. -// - -#define FFA_MAX_MAPPING_COUNT 10 - -// -// FF-A simple notification service GUID {B510B3A3-59F6-4054-BA7A-FF2EB1EAC765} -// - -DEFINE_GUID(GUID_FFA_NOTIFY_SERVICE, 0xb510b3a3, 0x59f6, 0x4054, 0xba, 0x7a, 0xff, 0x2e, 0xb1, 0xea, 0xc7, 0x65); - -// -// FF-A Status Reporting -// - -#define FFA_ERROR 0x84000060 -#define FFA_SUCCESS_AARCH32 0x84000061 -#define FFA_SUCCESS_AARCH64 0xC4000061 -#define FFA_INTERRUPT 0x84000062 -#define FFA_OP_PAUSE 0xC4000097 -#define FFA_OP_RESUME 0xC4000098 -#define FFA_OP_ERROR 0xC400009A -#define FFA_RES_INFO_GET 0xC4000099 -#define FFA_RES_AVAILABLE 0xC4000096 -#define FFA_MSG_SEND_DIRECT_REQ2 0xC400008D -#define FFA_MSG_SEND_DIRECT_RESP2 0xC400008E - -// -// FF-A Function IDs -// - -#define FFA_VERSION 0x84000063 -#define FFA_FEATURES 0x84000064 -#define FFA_RX_ACQUIRE 0x84000084 -#define FFA_RX_RELEASE 0x84000065 -#define FFA_RXTX_MAP_AARCH32 0x84000066 -#define FFA_RXTX_MAP_AARCH64 0xC4000066 -#define FFA_RXTX_UNMAP 0x84000067 -#define FFA_PARTITION_INFO_GET 0x84000068 -#define FFA_PARTITION_INFO_GET_REGS 0xC400008B -#define FFA_ID_GET 0x84000069 -#define FFA_SPM_ID_GET 0x84000085 -#define FFA_CONSOLE_LOG_AARCH32 0x8400008A -#define FFA_CONSOLE_LOG_AARCH64 0xC400008A -#define FFA_MSG_WAIT 0x8400006B -#define FFA_YIELD 0x8400006C -#define FFA_RUN 0x8400006D -#define FFA_NORMAL_WORLD_RESUME 0x8400007C -#define FFA_MSG_SEND2 0x84000086 -#define FFA_MSG_SEND_DIRECT_REQ_AARCH32 0x8400006F -#define FFA_MSG_SEND_DIRECT_REQ_AARCH64 0xC400006F -#define FFA_MSG_SEND_DIRECT_RESP_AARCH32 0x84000070 -#define FFA_MSG_SEND_DIRECT_RESP_AARCH64 0xC4000070 -#define FFA_MSG_SEND_DIRECT_REQ2 0xC400008D -#define FFA_MSG_SEND_DIRECT_RESP2 0xC400008E -#define FFA_NOTIFICATION_BITMAP_CREATE 0x8400007D -#define FFA_NOTIFICATION_BITMAP_DESTROY 0x8400007E -#define FFA_NOTIFICATION_BIND 0x8400007F -#define FFA_NOTIFICATION_UNBIND 0x84000080 -#define FFA_NOTIFICATION_SET 0x84000081 -#define FFA_NOTIFICATION_GET 0x84000082 -#define FFA_NOTIFICATION_INFO_GET_AARCH32 0x84000083 -#define FFA_NOTIFICATION_INFO_GET_AARCH64 0xC4000083 -#define FFA_EL3_INTR_HANDLE 0x8400008C -#define FFA_SECONDARY_EP_REGISTER_AARCH32 0x84000087 -#define FFA_SECONDARY_EP_REGISTER_AARCH64 0xC4000087 - -// -// Legacy FF-A Functionalities, below are commented out so that it will not get added later... -// #define FFA_MSG_SEND 0x8400006E -// #define FFA_MSG_POLL 0x8400006A -// - -// -// FF-A Status Codes Type and Definitions -// - -typedef LONG FFA_STATUS; - -#define FFA_STATUS_SUCCESS 0 -#define FFA_STATUS_ERROR_NOT_SUPPORTED -1 -#define FFA_STATUS_ERROR_INVALID_PARAMETERS -2 -#define FFA_STATUS_ERROR_NO_MEMORY -3 -#define FFA_STATUS_ERROR_BUSY -4 -#define FFA_STATUS_ERROR_INTERRUPTED -5 -#define FFA_STATUS_ERROR_DENIED -6 -#define FFA_STATUS_ERROR_RETRY -7 -#define FFA_STATUS_ERROR_ABORTED -8 -#define FFA_STATUS_ERROR_NO_DATA -9 -#define FFA_STATUS_ERROR_NOT_READY -10 - -// -// FF-A Version Definitions -// - -#define FFA_CALLER_VERSION_MAJOR 1 -#define FFA_CALLER_VERSION_MINOR 2 - -typedef union _FFA_VERSION_NUMBER { - struct { - ULONG Minor : 16; - ULONG Major : 15; - ULONG Reserved : 1; - }; - ULONG Raw; -} FFA_VERSION_NUMBER, *PFFA_VERSION_NUMBER; - -// -// FF-A Features Definitions -// - -#define FFA_FEATURE_NPI 0x00000001 -#define FFA_FEATURE_SRI 0x00000002 -#define FFA_FEATURE_MEI 0x00000003 -#define FFA_FEATURE_NOTIFICATION 0x00000004 -#define FFA_FEATURE_COMPLETION_MECH 0x00000005 - -// -// FF-A Notification Features -// - -#define FFA_FEATURE_NOTIFICATION_PER_VCPU_MASK (1 << 0) - -// -// FF-A Completion mechanism -// - -#define FFA_FEATURE_COMPLETION_MECH_VALID_MASK (1 << 0) -#define FFA_FEATURE_COMPLETION_MECH_COOP_EN_MASK (1 << 1) - -// -// FF-A Partition information descriptor definition -// The structure below corresponds to the FFA Partition Information Descriptor -// as defined in the FF-A specification. It was named to FF-A service info -// descriptor to match the main functionality of the structure. -// - -typedef union _FFA_SERVICE_INFO_DESC { - struct { - ULONGLONG PartitionId : 16; - ULONGLONG NumberOfExecutionContexts : 16; - ULONGLONG PartitionProperties : 32; - }; - ULONGLONG Raw; -} FFA_SERVICE_INFO_DESC, *PFFA_SERVICE_INFO_DESC; - -#pragma pack(push, 1) -typedef struct _FFA_SERVICE_INFO { - FFA_SERVICE_INFO_DESC ServiceInfoDesc; - GUID ServiceUuid; -} FFA_SERVICE_INFO, *PFFA_SERVICE_INFO; -#pragma pack(pop) - -// -// FF-A Notification Definitions -// - -#define FFA_NOTIFICATIONS_FLAG_PER_VCPU (0x1 << 0) -#define FFA_NOTIFICATIONS_FLAG_BITMAP_SP (0x1 << 0) -#define FFA_NOTIFICATIONS_FLAG_BITMAP_VM (0x1 << 1) -#define FFA_NOTIFICATIONS_FLAG_BITMAP_SPM (0x1 << 2) -#define FFA_NOTIFICATIONS_FLAG_BITMAP_HYP (0x1 << 3) - -// -// FF-A Parameter Structure -// - -typedef struct _FFA_PARAMETERS { - ULONGLONG Arg0; - ULONGLONG Arg1; - ULONGLONG Arg2; - ULONGLONG Arg3; - ULONGLONG Arg4; - ULONGLONG Arg5; - ULONGLONG Arg6; - ULONGLONG Arg7; - ULONGLONG Arg8; - ULONGLONG Arg9; - ULONGLONG Arg10; - ULONGLONG Arg11; - ULONGLONG Arg12; - ULONGLONG Arg13; - ULONGLONG Arg14; - ULONGLONG Arg15; - ULONGLONG Arg16; - ULONGLONG Arg17; -} FFA_PARAMETERS, *PFFA_PARAMETERS; - -// -// -------------------------------------------------------- Function Prototypes -// - -NTSTATUS -FfaRawSmcCall ( - _In_ PFFA_PARAMETERS InputParameters, - _Out_ PFFA_PARAMETERS OutputParameters - ); - -NTSTATUS -FfaQueryVersion ( - _Out_ PFFA_VERSION_NUMBER Version - ); - -NTSTATUS -FfaQueryFeature ( - _In_ ULONG FeatureId, - _Out_ PFFA_PARAMETERS Parameters - ); - -NTSTATUS -FfaQuerySriId ( - _Out_ PULONG SriId - ); - -NTSTATUS -FfaQueryNotificationFeatures ( - _Out_ PULONGLONG NotificationFeatures - ); - -NTSTATUS -FfaQueryPartitionInfo ( - _In_ PGUID ServiceId, - _Inout_ PFFA_SERVICE_INFO ServiceInfo, - _In_opt_ ULONG ServiceInfoBufferSize, - _Out_ PULONG ServiceCount, - _Out_ PULONG ServiceInfoSize - ); - -NTSTATUS -FfaQueryAllServiceInfo ( - _Inout_ PFFA_SERVICE_INFO ServiceInfo, - _In_opt_ ULONG ServiceInfoBufferSize, - _Out_ PULONG ServiceCount, - _Out_ PULONG ServiceInfoSize - ); - -NTSTATUS -FfaQueryPartitionInfoRegs ( - _In_ PGUID ServiceId, - _Out_ PFFA_SERVICE_INFO ServiceInfo - ); - -NTSTATUS -FfaQueryId ( - _Out_ PUSHORT FfaId - ); - -NTSTATUS -FfaEnableDisableNotification ( - _In_ USHORT PartitionId, - _In_ PGUID ServiceId, - _In_ USHORT MappingCount, - _In_ PUSHORT BitmapIndices, - _In_ PULONG NotifyIds, - _In_ BOOLEAN Enable - ); - -NTSTATUS -FfaRegisterRxTxBuffer ( - _In_ ULONGLONG RxBufferAddressVa, - _In_ ULONGLONG TxBufferAddressVa, - _In_ ULONGLONG RxBufferAddressPa, - _In_ ULONGLONG TxBufferAddressPa, - _In_ ULONGLONG BufferPageCount - ); - -NTSTATUS -FfaUnregisterRxTxBuffer ( - VOID - ); - -NTSTATUS -FfaReleaseRxBuffer ( - VOID - ); - -NTSTATUS -FfaUnregisterRxTxBuffer ( - VOID - ); - -NTSTATUS -FfaSendMsgSendDirectReq ( - _In_ USHORT PartitionId, - _In_ PFFA_PARAMETERS InputParameters, - _Out_ PFFA_PARAMETERS OutputParameters - ); - -NTSTATUS -FfaSendMsgSendDirectReq2 ( - _In_ USHORT PartitionId, - _In_ PGUID ServiceId, - _In_opt_ PFFA_DIRECT_REQ2_ASYNC_PARAMETERS AsyncParameters, - _In_ PFFA_PARAMETERS InputParameters, - _Out_ PFFA_PARAMETERS OutputParameters - ); - -NTSTATUS -FfaRun ( - _In_ PFFA_RUN_TARGET_INPUT_PARAMETERS RunInputParameters, - _Out_ PFFA_RUN_TARGET_OUTPUT_PARAMETERS RunOutputParameters - ); - -NTSTATUS -FfaNotificationBitMapCreate ( - ULONG VCpuCount - ); - -NTSTATUS -FfaNotificationBitMapDestroy ( - VOID - ); - -NTSTATUS -FfaNotificationBind ( - _In_ USHORT PartitionId, - _In_ ULONGLONG Flags, - _In_ ULONGLONG NotificationBitmap - ); - -NTSTATUS -FfaNotificationUnbind ( - _In_ USHORT PartitionId, - _In_ ULONGLONG NotificationBitmap - ); - -NTSTATUS -FfaNotificationGet ( - _In_ USHORT VCpuId, - _Inout_ PULONGLONG NotificationBitmap - ); diff --git a/ec/test-win/kmdf/ffainterface.h b/ec/test-win/kmdf/ffainterface.h deleted file mode 100644 index 1b57e53..0000000 --- a/ec/test-win/kmdf/ffainterface.h +++ /dev/null @@ -1,217 +0,0 @@ -/*++ - -Copyright (c) Microsoft Corporation - -Module Name: - - ffainterface.h - -Abstract: - - This file contains the interfaces required for FF-A support. - -Author: - - Yinghan Yang (yinghany) 18-Sep-2024 - -Environment: - - Kernel Mode - -Revision History: - ---*/ - - -#pragma once - -#pragma warning( push ) -#pragma warning( disable : 4115 ) /* nonstandard extension used : named type definition in parens */ -#pragma warning( disable : 4201 ) /* nonstandard extension used : nameless struct/union */ -#pragma warning( disable : 4214 ) /* nonstandard extension used : bit field types other then int */ - -#define FFA_NOTIFICATION_COUNT 64 -#define FFA_MSG_SEND_DIRECT_REQ2_PARAMETERS_VERSION_V1 0x1 -#define FFA_SEND_DIRECT_REQ2_BUFFER_SIZE (sizeof(ULONGLONG) * 14) -#define ENABLE_FFA_YIELD 1 - -DEFINE_GUID(GUID_CAPS_SERVICE_UUID, 0x330c1273, 0xfde5, 0x4757, 0x98, 0x19, 0x5b, 0x65, 0x39, 0x03, 0x75, 0x02); -// {17b862a4-1806-4faf-86b3-089a58353861} -// {330c1273-fde5-4757-9819-5b6539037502} - - -typedef struct _FFA_SEND_DIRECT_REQ2_BUFFER { - union { - struct { - - // - // Arg0-3 are reserved for framework use. User - // payload goes in the rest. - // - - ULONGLONG Arg4; - ULONGLONG Arg5; - ULONGLONG Arg6; - ULONGLONG Arg7; - ULONGLONG Arg8; - ULONGLONG Arg9; - ULONGLONG Arg10; - ULONGLONG Arg11; - ULONGLONG Arg12; - ULONGLONG Arg13; - ULONGLONG Arg14; - ULONGLONG Arg15; - ULONGLONG Arg16; - ULONGLONG Arg17; - }; - - UCHAR Buffer[FFA_SEND_DIRECT_REQ2_BUFFER_SIZE]; - }; -} FFA_SEND_DIRECT_REQ2_BUFFER, *PFFA_SEND_DIRECT_REQ2_BUFFER; - -typedef struct _FFA_PARAMETERS FFA_PARAMETERS, *PFFA_PARAMETERS; - -typedef struct _FFA_DIRECT_REQ2_PARAMETER_FLAGS { - struct { - ULONG FrameworkYieldHandling: 1; - ULONG Reserved: 30; - }; - - ULONG AsULONG; -} FFA_DIRECT_REQ2_PARAMETER_FLAGS, *PFFA_DIRECT_REQ2_PARAMETER_FLAGS; - -typedef struct _FFA_DIRECT_REQ2_ASYNC_PARAMETERS { - - // - // Input Parameters - // - - FFA_DIRECT_REQ2_PARAMETER_FLAGS Flags; - - // - // Output Parameters - // - - ULONGLONG DelayHintNs; - ULONG TargetId; - NTSTATUS Status; -} FFA_DIRECT_REQ2_ASYNC_PARAMETERS, *PFFA_DIRECT_REQ2_ASYNC_PARAMETERS; - -typedef struct _FFA_RUN_TARGET_INPUT_PARAMETERS { - ULONG TargetId; -} FFA_RUN_TARGET_INPUT_PARAMETERS, *PFFA_RUN_TARGET_INPUT_PARAMETERS; - -typedef struct _FFA_RUN_TARGET_OUTPUT_PARAMETERS { - ULONGLONG FfaStatus; - ULONGLONG DelayHintNs; - ULONG TargetId; - FFA_SEND_DIRECT_REQ2_BUFFER OutputBuffer; -} FFA_RUN_TARGET_OUTPUT_PARAMETERS, *PFFA_RUN_TARGET_OUTPUT_PARAMETERS; - -typedef struct _FFA_MSG_SEND_DIRECT_REQ2_PARAMETERS { - USHORT Version; - ULONG Reserved; - GUID ServiceUuid; - FFA_DIRECT_REQ2_ASYNC_PARAMETERS AsyncParameters; - FFA_SEND_DIRECT_REQ2_BUFFER InputBuffer; - FFA_SEND_DIRECT_REQ2_BUFFER OutputBuffer; -} FFA_MSG_SEND_DIRECT_REQ2_PARAMETERS, *PFFA_MSG_SEND_DIRECT_REQ2_PARAMETERS; - -typedef -NTSTATUS -(*PFFA_NOTIFY_CALLBACK) ( - _In_ PVOID Context, - _In_ LPGUID ServiceGuid, - _In_ ULONG NotifyCode - ); - -typedef struct _FFA_NOTIFICATION_REGISTRATION_PARAMETERS { - LPGUID ServiceUuid; - ULONG NotifyCode; - PVOID NotifyContext; - PFFA_NOTIFY_CALLBACK NotifyCallback; -} FFA_NOTIFICATION_REGISTRATION_PARAMETERS, *PFFA_NOTIFICATION_REGISTRATION_PARAMETERS; - -typedef PVOID _FFA_NOTIFICATION_REGISTRATION_TOKEN, FFA_NOTIFICATION_REGISTRATION_TOKEN, *PFFA_NOTIFICATION_REGISTRATION_TOKEN; - -typedef -_IRQL_requires_max_(PASSIVE_LEVEL) -_Must_inspect_result_ -NTSTATUS -FFA_REGISTER_NOTIFICATION ( - _In_ PFFA_NOTIFICATION_REGISTRATION_PARAMETERS RegistrationParameters, - _Out_ PFFA_NOTIFICATION_REGISTRATION_TOKEN Token - ); - -typedef FFA_REGISTER_NOTIFICATION *PFFA_REGISTER_NOTIFICATION; - -typedef -_IRQL_requires_max_(PASSIVE_LEVEL) -NTSTATUS -FFA_UNREGISTER_NOTIFICATION ( - _In_ FFA_NOTIFICATION_REGISTRATION_TOKEN Token - ); - -typedef FFA_UNREGISTER_NOTIFICATION *PFFA_UNREGISTER_NOTIFICATION; - -typedef -_Function_class_(FFA_MSG_SEND_DIRECT_REQ2) -NTSTATUS -FFA_MSG_SEND_DIRECT_REQ2 ( - _In_ PFFA_MSG_SEND_DIRECT_REQ2_PARAMETERS Parameters - ); - -typedef FFA_MSG_SEND_DIRECT_REQ2 *PFFA_MSG_SEND_DIRECT_REQ2; - -typedef -_Function_class_(FFA_RUN_TARGET) -NTSTATUS -FFA_RUN_TARGET ( - _In_ PFFA_RUN_TARGET_INPUT_PARAMETERS InputParameters, - _Out_ PFFA_RUN_TARGET_OUTPUT_PARAMETERS OutputParameters - ); - -typedef FFA_RUN_TARGET *PFFA_RUN_TARGET; - -typedef struct _FFA_INTERFACE_V1 { - PFFA_MSG_SEND_DIRECT_REQ2 SendDirectReq2; - PFFA_RUN_TARGET RunTarget; - PFFA_REGISTER_NOTIFICATION RegisterNotification; - PFFA_UNREGISTER_NOTIFICATION UnregisterNotification; -} FFA_INTERFACE_V1, *PFFA_INTERFACE_V1; - -typedef struct _FFA_INTERFACE_V1 FFA_INTERFACE, *PFFA_INTERFACE; - -#define FFA_INTERFACE_VERSION_1 0x1 - -_IRQL_requires_max_(PASSIVE_LEVEL) -_IRQL_requires_same_ -NTKERNELAPI -PFFA_INTERFACE -ExGetFfaInterface ( - _In_ ULONG Version - ); - -_IRQL_requires_max_(PASSIVE_LEVEL) -_IRQL_requires_same_ -NTKERNELAPI -VOID -ExFreeFfaInterface ( - _In_ PFFA_INTERFACE Interface - ); - -typedef -_IRQL_requires_max_(PASSIVE_LEVEL) -PFFA_INTERFACE -(*EX_GET_FFA_INTERFACE) ( - _In_ ULONG Version - ); - -typedef -_IRQL_requires_max_(PASSIVE_LEVEL) -VOID -(*EX_FREE_FFA_INTERFACE) ( - _In_ PFFA_INTERFACE Interface - ); - -#pragma warning( pop ) diff --git a/ec/test-win/kmdf/public.h b/ec/test-win/kmdf/public.h deleted file mode 100644 index 29765ed..0000000 --- a/ec/test-win/kmdf/public.h +++ /dev/null @@ -1,25 +0,0 @@ -/*++ -Module Name: - public.h - -Abstract: - - This module contains the common declarations shared by driver - and user applications. - -Environment: - user and kernel - ---*/ - -#define WHILE(a) \ -__pragma(warning(suppress:4127)) while(a) - -// -// Define an Interface Guid so that app can find the device and talk to it. -// - -DEFINE_GUID (GUID_DEVINTERFACE_ECTEST, - 0xcdc35b6e, 0xbe4, 0x4936, 0xbf, 0x5f, 0x55, 0x37, 0x38, 0xa, 0x7c, 0x1a); -// {CDC35B6E-0BE4-4936-BF5F-5537380A7C1A} - diff --git a/ec/test-win/kmdf/queue.c b/ec/test-win/kmdf/queue.c deleted file mode 100644 index 9ea725b..0000000 --- a/ec/test-win/kmdf/queue.c +++ /dev/null @@ -1,598 +0,0 @@ -/*++ -Module Name: - queue.c - -Abstract: - This is a C version of a very simple sample driver that illustrates - how to use the driver framework and demonstrates best practices. - ---*/ - -#include "driver.h" -#include -#include -#include "wdm.h" -#include "wdmguid.h" -#include "..\inc\ectest.h" -#include "trace.h" -#include "queue.tmh" -#include "ffainterface.h" - -#ifdef ALLOC_PRAGMA -#pragma alloc_text (PAGE, ECTestQueueInitialize) -#endif - -#ifdef EC_TEST_NOTIFICATIONS -// Globals -NotificationRsp_t m_NotifyStats = {0}; - -/** - * Function: NTSTATUS NotificationCallback - * - * Description: - * Callback function for handling ACPI notifications. - * - * This function is called when an ACPI notification is received. It updates - * the notification statistics with the current timestamp and the notification - * value. - * - * Parameters: - * Context - A pointer to the context information for the callback. - * NotifyValue - The value associated with the ACPI notification. - * - * Return Value: - * VOID - * - */ -VOID NotificationCallback( - PVOID Context, - ULONG NotifyValue - ) -{ - LARGE_INTEGER timestamp; - WDFREQUEST request = NULL; - size_t rspSize = 0; - NotificationRsp_t *rsp = NULL; - NTSTATUS status = STATUS_SUCCESS; - - Trace(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "Notification received: %lu\n", NotifyValue); - - KeQuerySystemTimePrecise(×tamp); - - m_NotifyStats.count++; - m_NotifyStats.timestamp = timestamp.QuadPart; - m_NotifyStats.lastevent = NotifyValue; - - WDFDEVICE device = (WDFDEVICE)Context; - PDEVICE_CONTEXT deviceContext = DeviceContextGet(device); - - WdfWaitLockAcquire(deviceContext->NotificationLock, NULL); - if (deviceContext->PendingRequest != NULL) { - request = deviceContext->PendingRequest; - deviceContext->PendingRequest = NULL; - } - WdfWaitLockRelease(deviceContext->NotificationLock); - - if (request != NULL) { - // Proceed only if the request is not cancelled - if (STATUS_CANCELLED != WdfRequestUnmarkCancelable(request)) { - // Retrieve the output buffer from the request - status = WdfRequestRetrieveOutputBuffer(request, sizeof(NotificationRsp_t), &rsp, &rspSize); - if (NT_SUCCESS(status)) { - // Copy the notification data to the output buffer - RtlCopyMemory(rsp, &m_NotifyStats, sizeof(NotificationRsp_t)); - - Trace(TRACE_LEVEL_INFORMATION, TRACE_QUEUE,"Completing 0x%llx with Success \n", (UINT64)request); - WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, sizeof(NotificationRsp_t)); - } else { - Trace(TRACE_LEVEL_ERROR, TRACE_QUEUE,"Completing 0x%llx with status %!STATUS!\n", (UINT64)request, status); - WdfRequestComplete(request, status); - } - } else { - Trace(TRACE_LEVEL_ERROR, TRACE_QUEUE,"Request 0x%llx was cancelled\n", (UINT64)request); - // If no request available, just log the notification - Trace(TRACE_LEVEL_ERROR, TRACE_QUEUE,"Not delivered to app : %lu \n", NotifyValue); - } - } else { - // If no request was pending, just log the notification - Trace(TRACE_LEVEL_ERROR, TRACE_QUEUE,"Not delivered to app : %lu \n", NotifyValue); - } -} - -#ifdef ENABLE_NOTIFICATION_SIMULATION -/* - * Function: VOID TimerCallback - * - * Description: - * Timer routine to simulate receiving the Notification at the driver. - * This function is called when the timer expires. - * - * Parameters: - * Timer - The Timer object. - * - * Return Value: - * VOID - * - */ -VOID TimerCallback(WDFTIMER Timer) -{ - WDFDEVICE device = WdfTimerGetParentObject(Timer); - - // Get the current system time - LARGE_INTEGER systemTime; - KeQuerySystemTime(&systemTime); - - // Use the low part of the system time as a random value - ULONG notifyValue = (ULONG)(systemTime.LowPart ^ systemTime.HighPart); - - Trace(TRACE_LEVEL_INFORMATION, TRACE_QUEUE,"Notification Triggerd: %lu\n", notifyValue); - NotificationCallback((PVOID)device, notifyValue); -} -#endif // ENABLE_NOTIFICATION_SIMULATION - -/* - * Function: NTSTATUS SetupNotification - * - * Description: - * Sets up ACPI notifications for the specified device. - * - * Parameters: - * device - The WDFDEVICE object representing the device. - * - * Return Value: - * NTSTATUS status code indicating the success or failure of the operation. - * - */ -NTSTATUS SetupNotification(WDFDEVICE device) -{ - ACPI_INTERFACE_STANDARD2 acpiInterface; - NTSTATUS status = STATUS_SUCCESS; - - status = WdfFdoQueryForInterface(device, - &GUID_ACPI_INTERFACE_STANDARD2, - (PINTERFACE) &acpiInterface, - sizeof(ACPI_INTERFACE_STANDARD2), - 1, - NULL); - - if (NT_SUCCESS(status)) { - status = acpiInterface.RegisterForDeviceNotifications(acpiInterface.Context, - NotificationCallback, - device); - } - return status; -} - -/* - * Function: VOID ECTestEvtRequestCancel - * - * Description: - * Handles the cancellation of a pending request. - * - * Parameters: - * Request - The WDFREQUEST object representing the request. - * - * Return Value: - * VOID - * - */ -VOID ECTestEvtRequestCancel(WDFREQUEST Request) -{ - WDFDEVICE device = WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)); - PDEVICE_CONTEXT deviceContext = DeviceContextGet(device); - - Trace(TRACE_LEVEL_INFORMATION, TRACE_QUEUE,"Cancel Request received for Request 0x%llx \n", (UINT64)Request); - - WdfWaitLockAcquire(deviceContext->NotificationLock, NULL); - if (deviceContext->PendingRequest == Request) { - Trace(TRACE_LEVEL_INFORMATION, TRACE_QUEUE,"Request found & cleared from pending list\n"); - deviceContext->PendingRequest = NULL; - } else { - Trace(TRACE_LEVEL_ERROR, TRACE_QUEUE,"Request not found in pending list\n"); - } - WdfWaitLockRelease(deviceContext->NotificationLock); - - Trace(TRACE_LEVEL_INFORMATION, TRACE_QUEUE,"Completing the request 0x%llx with STATUS_CANCELLED\n", (UINT64)Request); - WdfRequestComplete(Request, - STATUS_CANCELLED); -} - -/* - * Function: NTSTATUS NotificationGet - * - * Description: - * Handles the NotificationGet request. - * - * Parameters: - * DeviceObject - The WDFDEVICE object representing the device. - * Request - The WDFREQUEST object representing the request. - * - * Return Value: - * NTSTATUS status code indicating the success or failure of the operation. - * - */ -NTSTATUS NotificationGet(WDFDEVICE Device, WDFREQUEST Request) -{ - PDEVICE_CONTEXT deviceContext = DeviceContextGet(Device); - - WdfWaitLockAcquire(deviceContext->NotificationLock, NULL); - if (deviceContext->PendingRequest != NULL) { - WdfWaitLockRelease(deviceContext->NotificationLock); - - Trace(TRACE_LEVEL_ERROR, TRACE_QUEUE,"Request 0x%llx already pending\n", (UINT64)deviceContext->PendingRequest); - // If a request is already pending, complete the new request with STATUS_DEVICE_BUSY - return STATUS_DEVICE_BUSY; - } - - // Keeping this simple. Only one request can be pended at a time (since only 1 app is supported at a time) - deviceContext->PendingRequest = Request; - Trace(TRACE_LEVEL_INFORMATION, TRACE_QUEUE,"Saving Request 0x%llx to pending list\n", (UINT64)deviceContext->PendingRequest); - WdfWaitLockRelease(deviceContext->NotificationLock); - - WdfRequestMarkCancelable(Request, ECTestEvtRequestCancel); - return STATUS_PENDING; -} -#endif // EC_TEST_NOTIFICATIONS -/* - * Function: NTSTATUS ECTestQueueInitialize - * - * Description: - * The ECTestQueueInitialize function configures and creates a default I/O queue for a specified device. - * It sets up the queue to handle device control requests and ensures that requests not forwarded to other queues are dispatched here. - * - * Parameters: - * WDFDEVICE Device: A handle to the framework device object. - * - * Return Value: - * Returns an NTSTATUS value indicating the success or failure of the queue creation. - * If the queue is successfully created, it returns STATUS_SUCCESS. Otherwise, it returns an appropriate error code. - */ -NTSTATUS -ECTestQueueInitialize( - WDFDEVICE Device - ) -{ - NTSTATUS status; - WDF_IO_QUEUE_CONFIG queueConfig; - - PAGED_CODE(); - - // - // Configure a default queue so that requests that are not - // configure-fowarded using WdfDeviceConfigureRequestDispatching to goto - // other queues get dispatched here. - // NOTE: Dispatch is parallel to allow app to pend a notification requests along - // with DSM request - // - WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE( - &queueConfig, -#ifdef EC_TEST_NOTIFICATIONS - WdfIoQueueDispatchParallel -#else - WdfIoQueueDispatchSequential -#endif - ); - - queueConfig.EvtIoDeviceControl = ECTestEvtIoDeviceControl; - - status = WdfIoQueueCreate( - Device, - &queueConfig, - WDF_NO_OBJECT_ATTRIBUTES, - WDF_NO_HANDLE - ); - - if( !NT_SUCCESS(status) ) { - Trace(TRACE_LEVEL_ERROR, TRACE_QUEUE,"WdfIoQueueCreate failed 0x%x\n",status); - return status; - } - -#ifdef EC_TEST_NOTIFICATIONS - status = SetupNotification(Device); -#endif // EC_TEST_NOTIFICATIONS - - return status; -} - -/* - * Function: NTSTATUS FfaDrvTestDirectCall - * - * Description: - * Test function to directly make FFA call through the ffadrv interface rather than through ACPI - * - * Parameters: - * None - * - * Return Value: - * Returns an NTSTATUS value indicating the success or failure of FFA command - * If - */ -NTSTATUS -FfaDrvTestDirectCall(VOID) -{ - NTSTATUS status = STATUS_SUCCESS; - UNICODE_STRING GetFfaInterfaceRoutineName; - RtlInitUnicodeString(&GetFfaInterfaceRoutineName, L"ExGetFfaInterface"); - EX_GET_FFA_INTERFACE GetFfaInterfaceRoutine = (EX_GET_FFA_INTERFACE) MmGetSystemRoutineAddress(&GetFfaInterfaceRoutineName); - PFFA_INTERFACE pFfaInterface = GetFfaInterfaceRoutine(FFA_INTERFACE_VERSION_1); - - if(pFfaInterface == NULL) { - Trace(TRACE_LEVEL_ERROR, TRACE_QUEUE,"pFfaInterface is NULL\n"); - status = STATUS_INVALID_PARAMETER; - } else { - FFA_MSG_SEND_DIRECT_REQ2_PARAMETERS m_FfaParameters; - memset(&m_FfaParameters, 0, sizeof(m_FfaParameters)); - m_FfaParameters.Version = FFA_MSG_SEND_DIRECT_REQ2_PARAMETERS_VERSION_V1; - m_FfaParameters.AsyncParameters.Flags.FrameworkYieldHandling = ENABLE_FFA_YIELD; - RtlCopyMemory(&m_FfaParameters.ServiceUuid, - &GUID_CAPS_SERVICE_UUID, - sizeof(GUID)); - m_FfaParameters.InputBuffer.Arg4 = 0x1; // GET_CAPS - status = pFfaInterface->SendDirectReq2(&m_FfaParameters); - } - - return status; -} - -/* - * Function: VOID WorkItemCallback - * - * Description: - * The WorkItemCallback function is a callback function that processes a work item in a KMDF driver. - * It retrieves the output buffer, creates a preallocated memory object, and sends an internal IOCTL request to the device. - * The function then completes the request with the appropriate status and information. - * - * Parameters: - * WDFWORKITEM WorkItem: A handle to the work item being processed. - * - * Return Value: - * This function does not return a value. - */ -VOID -WorkItemCallback( - _In_ WDFWORKITEM WorkItem - ) -{ - PWORKITEM_CONTEXT context = WorkItemGetContext(WorkItem); - - // Input buffer should be one of the ACPI buffer types documented here - // https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/acpiioct/ - void *inputBuffer = NULL; - WDF_MEMORY_DESCRIPTOR inputMemDesc; - WDF_MEMORY_DESCRIPTOR outputMemDesc; - WDFMEMORY outputMemory = WDF_NO_HANDLE; - WDF_OBJECT_ATTRIBUTES attributes; - ULONG BytesReturned = 0; - NTSTATUS status = STATUS_SUCCESS; - PCHAR outBuf = NULL; - size_t outSize = 0; - size_t bufSize = 0; - - status = WdfRequestRetrieveInputBuffer(context->Request, 0, &inputBuffer, &bufSize); - if(!NT_SUCCESS(status)) { - status = STATUS_INSUFFICIENT_RESOURCES; - goto Cleanup; - } - - // Determine the size of output buffer and only give this much space to ACPI request - status = WdfRequestRetrieveOutputBuffer(context->Request, 0, &outBuf, &outSize); - if(!NT_SUCCESS(status)) { - status = STATUS_INSUFFICIENT_RESOURCES; - goto Cleanup; - } - - WDF_OBJECT_ATTRIBUTES_INIT(&attributes); - attributes.ParentObject = context->Device; - status = WdfMemoryCreatePreallocated(&attributes, - outBuf, - outSize, - &outputMemory); - - if(!NT_SUCCESS(status)) { - status = STATUS_INSUFFICIENT_RESOURCES; - goto Cleanup; - } - - - - WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&inputMemDesc, inputBuffer, (ULONG)bufSize); - WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&outputMemDesc, outputMemory, NULL); - - LARGE_INTEGER timestamp; - KeQuerySystemTimePrecise(×tamp); - Trace(TRACE_LEVEL_ERROR, TRACE_QUEUE,"Before ACPI Call: %llu\n", timestamp.QuadPart); - status = WdfIoTargetSendInternalIoctlSynchronously( - WdfDeviceGetIoTarget(context->Device), - NULL, - IOCTL_ACPI_EVAL_METHOD_EX, - &inputMemDesc, - &outputMemDesc, - NULL, - (PULONG_PTR)&BytesReturned); - KeQuerySystemTimePrecise(×tamp); - Trace(TRACE_LEVEL_ERROR, TRACE_QUEUE,"After ACPI Call: %llu\n", timestamp.QuadPart); - - -#if defined(EC_TEST_NOTIFICATIONS) && defined(ENABLE_NOTIFICATION_SIMULATION) - if (NT_SUCCESS(status)) { - PDEVICE_CONTEXT deviceContext = DeviceContextGet(context->Device); - if(deviceContext->Timer != NULL) { - // Toggle the timer - if (FALSE == WdfTimerStart(deviceContext->Timer, WDF_REL_TIMEOUT_IN_MS(200))) { - Trace(TRACE_LEVEL_INFORMATION, TRACE_QUEUE,"Starting Notification Simulation timer\n"); - } else{ - Trace(TRACE_LEVEL_INFORMATION, TRACE_QUEUE,"Stopping Notification Simulation timer\n"); - WdfTimerStop(deviceContext->Timer, FALSE); - } - } - } -#endif - -Cleanup: - WdfRequestSetInformation(context->Request,BytesReturned); - WdfRequestComplete( context->Request, status); -} - -/* - * Function: NTSTATUS CreateAndEnqueueWorkItem - * - * Description: - * The CreateAndEnqueueWorkItem function creates a work item and enqueues it for execution. - * It initializes the work item configuration and context, and sets the callback function for the work item. - * - * Parameters: - * WDFDEVICE Device: A handle to the framework device object. - * WDFREQUEST Request: A handle to the framework request object. - * - * Return Value: - * Returns an NTSTATUS value indicating the success or failure of the work item creation and enqueueing. - * If the work item is successfully created and enqueued, it returns STATUS_SUCCESS. Otherwise, it returns an appropriate error code. - */ -NTSTATUS -CreateAndEnqueueWorkItem( - _In_ WDFDEVICE Device, - _In_ WDFREQUEST Request - ) -{ - NTSTATUS status; - WDF_OBJECT_ATTRIBUTES attributes; - WDF_WORKITEM_CONFIG workitemConfig; - WDFWORKITEM workItem; - PWORKITEM_CONTEXT context; - - WDF_WORKITEM_CONFIG_INIT(&workitemConfig, WorkItemCallback); - - WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, WORKITEM_CONTEXT); - attributes.ParentObject = Device; - - status = WdfWorkItemCreate(&workitemConfig, &attributes, &workItem); - if (!NT_SUCCESS(status)) { - Trace(TRACE_LEVEL_ERROR, TRACE_QUEUE,"WdfWorkItemCreate failed: %!STATUS!\n", status); - return status; - } - - context = WorkItemGetContext(workItem); - context->Device = Device; - context->Request = Request; - - WdfWorkItemEnqueue(workItem); - - return status; -} - -/* - * Function: VOID ECTestEvtIoDeviceControl - * - * Description: - * The ECTestEvtIoDeviceControl function handles device control requests for a KMDF driver. - * It processes the specified I/O control code and enqueues a work item for ACPI method evaluation if applicable. - * - * Parameters: - * WDFQUEUE Queue: A handle to the framework queue object. - * WDFREQUEST Request: A handle to the framework request object. - * size_t OutputBufferLength: The length of the output buffer. - * size_t InputBufferLength: The length of the input buffer. - * ULONG IoControlCode: The I/O control code specifying the operation to perform. - * - * Return Value: - * This function does not return a value. - */ -VOID -ECTestEvtIoDeviceControl( - IN WDFQUEUE Queue, - IN WDFREQUEST Request, - IN size_t OutputBufferLength, - IN size_t InputBufferLength, - IN ULONG IoControlCode - ) -{ - NTSTATUS status = STATUS_SUCCESS;// Assume success - BOOLEAN completeRequest = TRUE; - - if(!OutputBufferLength || !InputBufferLength) - { - WdfRequestComplete(Request, STATUS_INVALID_PARAMETER); - return; - } - - WDFDEVICE device = WdfIoQueueGetDevice(Queue); - - // - // Determine which I/O control code was specified. - // - - switch (IoControlCode) - { - case IOCTL_ACPI_EVAL_METHOD_EX: - Trace(TRACE_LEVEL_INFORMATION, TRACE_QUEUE,"IOCTL_ACPI_EVAL_METHOD_EX\n"); - - // Request is retrieved and handled in the callback - status = CreateAndEnqueueWorkItem(device, Request); - // If we enqueue it successfully it will be completed later, otherwise complete with status - if (NT_SUCCESS(status)) { - Trace(TRACE_LEVEL_INFORMATION, TRACE_QUEUE,"EVAL request 0x%llx pended\n", (UINT64)Request); - // Request will be completed later in work item callback - - completeRequest = FALSE; - } else { - Trace(TRACE_LEVEL_ERROR, TRACE_QUEUE,"CreateAndEnqueueWorkItem failed\n"); - } - break; -#ifdef EC_TEST_NOTIFICATIONS - case IOCTL_GET_NOTIFICATION: - Trace(TRACE_LEVEL_INFORMATION, TRACE_QUEUE,"IOCTL_GET_NOTIFICATION \n"); - status = NotificationGet(device, Request); - - // If we enqueue it successfully it will be completed later, otherwise complete with status - if (NT_SUCCESS(status)) { - completeRequest = FALSE; - } - break; -#endif // EC_TEST_NOTIFICATIONS - -#ifdef EC_TEST_SHARED_BUFFER - case IOCTL_READ_RX_BUFFER: - size_t rxSize = 0; - RxBufferRsp_t *rxrsp = NULL; - - // Determine the size of output buffer and only give this much space to ACPI request - status = WdfRequestRetrieveOutputBuffer(Request, 0, &rxrsp, &rxSize); - if(!NT_SUCCESS(status)) { - status = STATUS_INSUFFICIENT_RESOURCES; - break; - } - - PHYSICAL_ADDRESS physicalAddress; - PVOID virtualAddress; - ULONG64 value; - - // Set the physical address - physicalAddress.QuadPart = SBSAQEMU_SHARED_MEM_BASE; - - // Map the physical address to a virtual address - virtualAddress = MmMapIoSpaceEx(physicalAddress, sizeof(ULONG64), PAGE_READONLY); - - if (virtualAddress == NULL) { - status = STATUS_INSUFFICIENT_RESOURCES; - break; - } - - // Read the value from the virtual address - value = *(volatile ULONG64*)virtualAddress; - - // Unmap the virtual address - MmUnmapIoSpace(virtualAddress, sizeof(ULONG64)); - - rxrsp->data = value; - break; -#endif // EC_TEST_SHARED_BUFFER - - default: - status = STATUS_INVALID_PARAMETER; - break; - } - - if (completeRequest) { - WdfRequestComplete(Request, status); - } -} diff --git a/ec/test-win/kmdf/queue.h b/ec/test-win/kmdf/queue.h deleted file mode 100644 index 5bdfcf4..0000000 --- a/ec/test-win/kmdf/queue.h +++ /dev/null @@ -1,40 +0,0 @@ -/*++ -Module Name: - queue.h - -Abstract: - - This is a C version of a very simple sample driver that illustrates - how to use the driver framework and demonstrates best practices. ---*/ - -#include - -// -// This is the context that can be placed per queue -// and would contain per queue information. -// -typedef struct _WORKITEM_CONTEXT { - WDFDEVICE Device; - WDFQUEUE Queue; - WDFREQUEST Request; - ACPI_EVAL_INPUT_BUFFER_V1_EX *Buffer; -} WORKITEM_CONTEXT, *PWORKITEM_CONTEXT; - -WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WORKITEM_CONTEXT, WorkItemGetContext); - -NTSTATUS -ECTestQueueInitialize( - WDFDEVICE hDevice - ); - -EVT_WDF_IO_QUEUE_CONTEXT_DESTROY_CALLBACK ECTestEvtIoQueueContextDestroy; - -VOID -ECTestEvtIoDeviceControl( - IN WDFQUEUE Queue, - IN WDFREQUEST Request, - IN size_t OutputBufferLength, - IN size_t InputBufferLength, - IN ULONG IoControlCode - ); diff --git a/ec/test-win/kmdf/trace.h b/ec/test-win/kmdf/trace.h deleted file mode 100644 index b5f2ad1..0000000 --- a/ec/test-win/kmdf/trace.h +++ /dev/null @@ -1,32 +0,0 @@ -/*++ -Module Name: - trace.h - -Abstract: - Header file for the debug tracing related function definitions and macros. - -Environment: - Kernel mode ---*/ - -#include // For TRACE_LEVEL definitions - -// Define the tracing flags. -// Tracing GUID - {2b869d11-4cbb-4080-b229-01f971dba7a8} - - -#define WPP_CONTROL_GUIDS \ - WPP_DEFINE_CONTROL_GUID( EcTestTraceGuid, (2b869d11,4cbb,4080,b229,01f971dba7a8), \ - WPP_DEFINE_BIT(TRACE_ALL) /* bit 0 = 0x00000001 */ \ - WPP_DEFINE_BIT(TRACE_DRIVER) /* bit 1 = 0x00000002 */\ - WPP_DEFINE_BIT(TRACE_DEVICE) /* bit 2 = 0x00000004 */\ - WPP_DEFINE_BIT(TRACE_QUEUE) /* bit 3 = 0x00000008 */\ - ) - -#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) WPP_LEVEL_LOGGER(flags) -#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl) - -// This comment block is scanned by the trace preprocessor to define our Trace function. -// begin_wpp config -// FUNC Trace(LEVEL, FLAGS, MSG, ...); -// end_wpp