| /* | |
| * What processor? | |
| * | |
| * Copyright 1995,1997 Morten Welinder | |
| * Copyright 1997-1998 Marcus Meissner | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library 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 | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |
| */ | |
| #include "config.h" | |
| #include "wine/port.h" | |
| #include <stdarg.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #ifdef HAVE_SYS_TIME_H | |
| # include <sys/time.h> | |
| #endif | |
| #define NONAMELESSUNION | |
| #define NONAMELESSSTRUCT | |
| #include "ntstatus.h" | |
| #define WIN32_NO_STATUS | |
| #include "windef.h" | |
| #include "winbase.h" | |
| #include "winnt.h" | |
| #include "winternl.h" | |
| #include "psapi.h" | |
| #include "ddk/wdm.h" | |
| #include "wine/unicode.h" | |
| #include "kernel_private.h" | |
| #include "wine/debug.h" | |
| WINE_DEFAULT_DEBUG_CHANNEL(reg); | |
| #define SHARED_DATA ((KSHARED_USER_DATA*)0x7ffe0000) | |
| /**************************************************************************** | |
| * QueryPerformanceCounter (KERNEL32.@) | |
| * | |
| * Get the current value of the performance counter. | |
| * | |
| * PARAMS | |
| * counter [O] Destination for the current counter reading | |
| * | |
| * RETURNS | |
| * Success: TRUE. counter contains the current reading | |
| * Failure: FALSE. | |
| * | |
| * SEE ALSO | |
| * See QueryPerformanceFrequency. | |
| */ | |
| BOOL WINAPI QueryPerformanceCounter(PLARGE_INTEGER counter) | |
| { | |
| NtQueryPerformanceCounter( counter, NULL ); | |
| return TRUE; | |
| } | |
| /**************************************************************************** | |
| * QueryPerformanceFrequency (KERNEL32.@) | |
| * | |
| * Get the resolution of the performance counter. | |
| * | |
| * PARAMS | |
| * frequency [O] Destination for the counter resolution | |
| * | |
| * RETURNS | |
| * Success. TRUE. Frequency contains the resolution of the counter. | |
| * Failure: FALSE. | |
| * | |
| * SEE ALSO | |
| * See QueryPerformanceCounter. | |
| */ | |
| BOOL WINAPI QueryPerformanceFrequency(PLARGE_INTEGER frequency) | |
| { | |
| LARGE_INTEGER counter; | |
| NtQueryPerformanceCounter( &counter, frequency ); | |
| return TRUE; | |
| } | |
| /*********************************************************************** | |
| * GetSystemInfo [KERNEL32.@] | |
| * | |
| * Get information about the system. | |
| * | |
| * RETURNS | |
| * Nothing. | |
| */ | |
| VOID WINAPI GetSystemInfo( | |
| LPSYSTEM_INFO si /* [out] Destination for system information, may not be NULL */) | |
| { | |
| NTSTATUS nts; | |
| SYSTEM_CPU_INFORMATION sci; | |
| TRACE("si=0x%p\n", si); | |
| if ((nts = NtQuerySystemInformation( SystemCpuInformation, &sci, sizeof(sci), NULL )) != STATUS_SUCCESS) | |
| { | |
| SetLastError(RtlNtStatusToDosError(nts)); | |
| return; | |
| } | |
| si->u.s.wProcessorArchitecture = sci.Architecture; | |
| si->u.s.wReserved = 0; | |
| si->dwPageSize = system_info.PageSize; | |
| si->lpMinimumApplicationAddress = system_info.LowestUserAddress; | |
| si->lpMaximumApplicationAddress = system_info.HighestUserAddress; | |
| si->dwActiveProcessorMask = system_info.ActiveProcessorsAffinityMask; | |
| si->dwNumberOfProcessors = system_info.NumberOfProcessors; | |
| switch (sci.Architecture) | |
| { | |
| case PROCESSOR_ARCHITECTURE_INTEL: | |
| switch (sci.Level) | |
| { | |
| case 3: si->dwProcessorType = PROCESSOR_INTEL_386; break; | |
| case 4: si->dwProcessorType = PROCESSOR_INTEL_486; break; | |
| case 5: | |
| case 6: si->dwProcessorType = PROCESSOR_INTEL_PENTIUM; break; | |
| default: si->dwProcessorType = PROCESSOR_INTEL_PENTIUM; break; | |
| } | |
| break; | |
| case PROCESSOR_ARCHITECTURE_PPC: | |
| switch (sci.Level) | |
| { | |
| case 1: si->dwProcessorType = PROCESSOR_PPC_601; break; | |
| case 3: | |
| case 6: si->dwProcessorType = PROCESSOR_PPC_603; break; | |
| case 4: si->dwProcessorType = PROCESSOR_PPC_604; break; | |
| case 9: si->dwProcessorType = PROCESSOR_PPC_604; break; | |
| case 20: si->dwProcessorType = PROCESSOR_PPC_620; break; | |
| default: si->dwProcessorType = 0; | |
| } | |
| break; | |
| case PROCESSOR_ARCHITECTURE_AMD64: | |
| si->dwProcessorType = PROCESSOR_AMD_X8664; | |
| break; | |
| case PROCESSOR_ARCHITECTURE_ARM: | |
| switch (sci.Level) | |
| { | |
| case 4: si->dwProcessorType = PROCESSOR_ARM_7TDMI; break; | |
| default: si->dwProcessorType = PROCESSOR_ARM920; | |
| } | |
| break; | |
| default: | |
| FIXME("Unknown processor architecture %x\n", sci.Architecture); | |
| si->dwProcessorType = 0; | |
| } | |
| si->dwAllocationGranularity = system_info.AllocationGranularity; | |
| si->wProcessorLevel = sci.Level; | |
| si->wProcessorRevision = sci.Revision; | |
| } | |
| /*********************************************************************** | |
| * GetNativeSystemInfo [KERNEL32.@] | |
| */ | |
| VOID WINAPI GetNativeSystemInfo( | |
| LPSYSTEM_INFO si /* [out] Destination for system information, may not be NULL */) | |
| { | |
| BOOL is_wow64; | |
| GetSystemInfo(si); | |
| IsWow64Process(GetCurrentProcess(), &is_wow64); | |
| if (is_wow64) | |
| { | |
| if (si->u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) | |
| { | |
| si->u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64; | |
| si->dwProcessorType = PROCESSOR_AMD_X8664; | |
| } | |
| else | |
| { | |
| FIXME("Add the proper information for %d in wow64 mode\n", | |
| si->u.s.wProcessorArchitecture); | |
| } | |
| } | |
| } | |
| /*********************************************************************** | |
| * IsProcessorFeaturePresent [KERNEL32.@] | |
| * | |
| * Determine if the cpu supports a given feature. | |
| * | |
| * RETURNS | |
| * TRUE, If the processor supports feature, | |
| * FALSE otherwise. | |
| */ | |
| BOOL WINAPI IsProcessorFeaturePresent ( | |
| DWORD feature /* [in] Feature number, (PF_ constants from "winnt.h") */) | |
| { | |
| if (feature < PROCESSOR_FEATURE_MAX) | |
| return SHARED_DATA->ProcessorFeatures[feature]; | |
| else | |
| return FALSE; | |
| } | |
| /*********************************************************************** | |
| * K32GetPerformanceInfo (KERNEL32.@) | |
| */ | |
| BOOL WINAPI K32GetPerformanceInfo(PPERFORMANCE_INFORMATION info, DWORD size) | |
| { | |
| union | |
| { | |
| SYSTEM_PERFORMANCE_INFORMATION performance; | |
| SYSTEM_PROCESS_INFORMATION process; | |
| SYSTEM_BASIC_INFORMATION basic; | |
| } *sysinfo; | |
| SYSTEM_PROCESS_INFORMATION *spi; | |
| DWORD process_info_size; | |
| NTSTATUS status; | |
| TRACE( "(%p, %d)\n", info, size ); | |
| if (size < sizeof(*info)) | |
| { | |
| SetLastError( ERROR_BAD_LENGTH ); | |
| return FALSE; | |
| } | |
| memset( info, 0, sizeof(*info) ); | |
| info->cb = sizeof(*info); | |
| /* fields from SYSTEM_PROCESS_INFORMATION */ | |
| NtQuerySystemInformation( SystemProcessInformation, NULL, 0, &process_info_size ); | |
| for (;;) | |
| { | |
| sysinfo = HeapAlloc( GetProcessHeap(), 0, max(process_info_size, sizeof(*sysinfo)) ); | |
| if (!sysinfo) | |
| { | |
| SetLastError( ERROR_OUTOFMEMORY ); | |
| return FALSE; | |
| } | |
| status = NtQuerySystemInformation( SystemProcessInformation, &sysinfo->process, | |
| process_info_size, &process_info_size ); | |
| if (!status) break; | |
| if (status != STATUS_INFO_LENGTH_MISMATCH) | |
| goto err; | |
| HeapFree( GetProcessHeap(), 0, sysinfo ); | |
| } | |
| for (spi = &sysinfo->process;; spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset)) | |
| { | |
| info->ProcessCount++; | |
| info->HandleCount += spi->HandleCount; | |
| info->ThreadCount += spi->dwThreadCount; | |
| if (spi->NextEntryOffset == 0) break; | |
| } | |
| /* fields from SYSTEM_PERFORMANCE_INFORMATION */ | |
| status = NtQuerySystemInformation( SystemPerformanceInformation, &sysinfo->performance, | |
| sizeof(sysinfo->performance), NULL ); | |
| if (status) goto err; | |
| info->CommitTotal = sysinfo->performance.TotalCommittedPages; | |
| info->CommitLimit = sysinfo->performance.TotalCommitLimit; | |
| info->CommitPeak = sysinfo->performance.PeakCommitment; | |
| info->PhysicalAvailable = sysinfo->performance.AvailablePages; | |
| info->KernelTotal = sysinfo->performance.PagedPoolUsage + | |
| sysinfo->performance.NonPagedPoolUsage; | |
| info->KernelPaged = sysinfo->performance.PagedPoolUsage; | |
| info->KernelNonpaged = sysinfo->performance.NonPagedPoolUsage; | |
| /* fields from SYSTEM_BASIC_INFORMATION */ | |
| status = NtQuerySystemInformation( SystemBasicInformation, &sysinfo->basic, | |
| sizeof(sysinfo->basic), NULL ); | |
| if (status) goto err; | |
| info->PhysicalTotal = sysinfo->basic.MmNumberOfPhysicalPages; | |
| info->PageSize = sysinfo->basic.PageSize; | |
| err: | |
| HeapFree( GetProcessHeap(), 0, sysinfo ); | |
| if (status) | |
| { | |
| SetLastError( RtlNtStatusToDosError( status ) ); | |
| return FALSE; | |
| } | |
| return TRUE; | |
| } | |
| /*********************************************************************** | |
| * GetLargePageMinimum (KERNEL32.@) | |
| */ | |
| SIZE_T WINAPI GetLargePageMinimum(void) | |
| { | |
| #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) | |
| return 2 * 1024 * 1024; | |
| #endif | |
| FIXME("Not implemented on your platform/architecture.\n"); | |
| return 0; | |
| } | |
| /*********************************************************************** | |
| * GetActiveProcessorGroupCount (KERNEL32.@) | |
| */ | |
| WORD WINAPI GetActiveProcessorGroupCount(void) | |
| { | |
| FIXME("semi-stub, always returning 1\n"); | |
| return 1; | |
| } | |
| /*********************************************************************** | |
| * GetActiveProcessorCount (KERNEL32.@) | |
| */ | |
| DWORD WINAPI GetActiveProcessorCount(WORD group) | |
| { | |
| SYSTEM_INFO si; | |
| DWORD cpus; | |
| GetSystemInfo( &si ); | |
| cpus = si.dwNumberOfProcessors; | |
| FIXME("semi-stub, returning %u\n", cpus); | |
| return cpus; | |
| } |