PSHV_GLOBAL_DATA ShvVpAllocateGlobalData ( VOID ) { PHYSICAL_ADDRESS lowest, highest; PSHV_GLOBAL_DATA data; ULONG cpuCount, size; // // The entire address range is OK for this allocation // lowest.QuadPart = 0; highest.QuadPart = lowest.QuadPart - 1; // // Query the number of logical processors, including those potentially in // groups other than 0. This allows us to support >64 processors. // cpuCount = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); // // Each processor will receive its own slice of per-virtual processor data. // size = FIELD_OFFSET(SHV_GLOBAL_DATA, VpData) + cpuCount * sizeof(SHV_VP_DATA); // // Allocate a contiguous chunk of RAM to back this allocation and make sure // that it is RW only, instead of RWX, by using the new Windows 8 API. // #if TARGETVERSION > 7 data = (PSHV_GLOBAL_DATA)MmAllocateContiguousNodeMemory(size, lowest, highest, lowest, PAGE_READWRITE, MM_ANY_NODE_OK); #else data = (PSHV_GLOBAL_DATA)MmAllocateContiguousMemory(size, highest); #endif // TARGETVERSION > 7 if (data != NULL) { // // Zero out the entire data region // __stosq((PULONGLONG)data, 0, size / sizeof(ULONGLONG)); } // // Return what is hopefully a valid pointer, otherwise NULL. // return data; }
/*++ Routine Description: Process mailbox property request. Arguments: DeviceContextPtr - Pointer to device context DataInPtr - Pointer to property data DataSize - Data size for input and output is the expected to be the same Request - WDF request object associated with this mailbox transaction Return Value: NTSTATUS --*/ _Use_decl_annotations_ NTSTATUS RpiqMailboxProperty ( DEVICE_CONTEXT* DeviceContextPtr, VOID* DataInPtr, ULONG DataSize, ULONG Channel, WDFREQUEST Request ) { NTSTATUS status; PHYSICAL_ADDRESS highAddress; PHYSICAL_ADDRESS lowAddress = { 0 }; PHYSICAL_ADDRESS boundaryAddress = { 0 }; PHYSICAL_ADDRESS addrProperty; RPIQ_REQUEST_CONTEXT* requestContextPtr; PAGED_CODE(); highAddress.QuadPart = HEX_1_G; if (DataInPtr == NULL || DataSize < sizeof(MAILBOX_HEADER)) { status = STATUS_INVALID_PARAMETER; goto End; } { WDF_OBJECT_ATTRIBUTES wdfObjectAttributes; WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE( &wdfObjectAttributes, RPIQ_REQUEST_CONTEXT); wdfObjectAttributes.EvtCleanupCallback = RpiqRequestContextCleanup; status = WdfObjectAllocateContext( Request, &wdfObjectAttributes, &requestContextPtr); if (!NT_SUCCESS(status)) { RPIQ_LOG_WARNING( "WdfObjectAllocateContext() failed %!STATUS!)", status); goto End; } } // Firmware expects mailbox request to be in contiguous memory requestContextPtr->PropertyMemory = MmAllocateContiguousNodeMemory( DataSize, lowAddress, highAddress, boundaryAddress, PAGE_NOCACHE | PAGE_READWRITE, MM_ANY_NODE_OK); if (requestContextPtr->PropertyMemory == NULL) { RPIQ_LOG_ERROR("RpiqMailboxProperty fail to allocate memory"); status = STATUS_INSUFFICIENT_RESOURCES; goto End; } requestContextPtr->PropertyMemorySize = DataSize; addrProperty = MmGetPhysicalAddress(requestContextPtr->PropertyMemory); RtlCopyMemory(requestContextPtr->PropertyMemory, DataInPtr, DataSize); status = RpiqMailboxWrite( DeviceContextPtr, Channel, addrProperty.LowPart + OFFSET_DIRECT_SDRAM, Request); if (!NT_SUCCESS(status)) { RPIQ_LOG_ERROR("RpiqMailboxWrite failed %!STATUS!", status); goto End; } End: return status; }