1
0
forked from 0ad/0ad

bugfixes+cleanup

aken: clean up debug strings
mahaf: use checked/free version of aken depending on config. refactor to
eliminate goto.
hpet: avoid undefined unmap if HPET not found
whrt/*: make sure all counter class data is initialized
whrt: prefer QPC over PMT (it's much faster?!)
winit: add some instrumentation
wutil: win_exe_dir and win_sys_dir shouldn't end in slash. fixed.

This was SVN commit r5116.
This commit is contained in:
janwas 2007-05-29 22:39:36 +00:00
parent fba692c8b5
commit cba876b246
11 changed files with 100 additions and 74 deletions

View File

@ -3,8 +3,6 @@ extern "C" { // must come before ntddk.h
#include <ntddk.h>
#include "aken.h"
#define KDPRINT KdPrint(("AKEN: ")); KdPrint
#define WIN32_NAME L"\\DosDevices\\Aken"
#define DEVICE_NAME L"\\Device\\Aken"
@ -36,7 +34,7 @@ static NTSTATUS AkenMapPhysicalMemory(const DWORD64 physicalAddress64, const DWO
ntStatus = ZwOpenSection(&hMemory, SECTION_ALL_ACCESS, &objectAttributes);
if(!NT_SUCCESS(ntStatus))
{
KDPRINT(("ZwOpenSection failed\n"));
KdPrint(("AkenMapPhysicalMemory: ZwOpenSection failed\n"));
return ntStatus;
}
}
@ -48,7 +46,7 @@ static NTSTATUS AkenMapPhysicalMemory(const DWORD64 physicalAddress64, const DWO
ntStatus = ObReferenceObjectByHandle(hMemory, SECTION_ALL_ACCESS, objectType, KernelMode, &physicalMemorySection, 0);
if(!NT_SUCCESS(ntStatus))
{
KDPRINT(("ObReferenceObjectByHandle failed\n"));
KdPrint(("AkenMapPhysicalMemory: ObReferenceObjectByHandle failed\n"));
goto close_handle;
}
}
@ -67,7 +65,7 @@ static NTSTATUS AkenMapPhysicalMemory(const DWORD64 physicalAddress64, const DWO
ntStatus = ZwMapViewOfSection(hMemory, hProcess, &virtualBaseAddress, zeroBits, mappedSize, &physicalBaseAddress, &mappedSize, inheritDisposition, allocationType, protect);
if(!NT_SUCCESS(ntStatus))
{
KDPRINT(("ZwMapViewOfSection failed\n"));
KdPrint(("AkenMapPhysicalMemory: ZwMapViewOfSection failed\n"));
goto close_handle;
}
@ -97,7 +95,7 @@ static NTSTATUS AkenUnmapPhysicalMemory(const DWORD64 virtualAddress)
NTSTATUS ntStatus = ZwUnmapViewOfSection(hProcess, baseAddress);
if(!NT_SUCCESS(ntStatus))
{
KDPRINT(("ZwUnmapViewOfSection failed\n"));
KdPrint(("AkenUnmapPhysicalMemory: ZwUnmapViewOfSection failed\n"));
return ntStatus;
}
@ -111,8 +109,6 @@ static NTSTATUS AkenUnmapPhysicalMemory(const DWORD64 virtualAddress)
static NTSTATUS AkenIoctlReadPort(PVOID buf, const ULONG inSize, ULONG& outSize)
{
KDPRINT(("IOCTL_AKEN_READ_PORT\n"));
if(inSize != sizeof(AkenReadPortIn) || outSize != sizeof(AkenReadPortOut))
return STATUS_BUFFER_TOO_SMALL;
@ -134,7 +130,7 @@ static NTSTATUS AkenIoctlReadPort(PVOID buf, const ULONG inSize, ULONG& outSize)
default:
return STATUS_INVALID_PARAMETER;
}
KDPRINT((" port %x = %x\n", port, value));
KdPrint(("AkenIoctlReadPort: port %x = %x\n", port, value));
AkenReadPortOut* out = (AkenReadPortOut*)buf;
out->value = value;
@ -143,8 +139,6 @@ static NTSTATUS AkenIoctlReadPort(PVOID buf, const ULONG inSize, ULONG& outSize)
static NTSTATUS AkenIoctlWritePort(PVOID buf, const ULONG inSize, ULONG& outSize)
{
KDPRINT(("IOCTL_AKEN_WRITE_PORT\n"));
if(inSize != sizeof(AkenWritePortIn) || outSize != 0)
return STATUS_BUFFER_TOO_SMALL;
@ -166,15 +160,13 @@ static NTSTATUS AkenIoctlWritePort(PVOID buf, const ULONG inSize, ULONG& outSize
default:
return STATUS_INVALID_PARAMETER;
}
KDPRINT((" port %x := %x\n", port, value));
KdPrint(("AkenIoctlWritePort: port %x := %x\n", port, value));
return STATUS_SUCCESS;
}
static NTSTATUS AkenIoctlMap(PVOID buf, const ULONG inSize, ULONG& outSize)
{
KDPRINT(("IOCTL_AKEN_MAP\n"));
if(inSize != sizeof(AkenMapIn) || outSize != sizeof(AkenMapOut))
return STATUS_BUFFER_TOO_SMALL;
@ -191,8 +183,6 @@ static NTSTATUS AkenIoctlMap(PVOID buf, const ULONG inSize, ULONG& outSize)
static NTSTATUS AkenIoctlUnmap(PVOID buf, const ULONG inSize, ULONG& outSize)
{
KDPRINT(("IOCTL_AKEN_UNMAP\n"));
if(inSize != sizeof(AkenUnmapIn) || outSize != 0)
return STATUS_BUFFER_TOO_SMALL;
@ -205,7 +195,7 @@ static NTSTATUS AkenIoctlUnmap(PVOID buf, const ULONG inSize, ULONG& outSize)
static NTSTATUS AkenIoctlUnknown(PVOID buf, const ULONG inSize, ULONG& outSize)
{
KDPRINT(("Unknown IOCTL\n"));
KdPrint(("AkenIoctlUnknown\n"));
outSize = 0;
return STATUS_INVALID_DEVICE_REQUEST;
}
@ -239,8 +229,7 @@ static inline AkenIoctl AkenIoctlFromCode(ULONG ioctlCode)
// entry points
//-----------------------------------------------------------------------------
// used as Create and Close entry point since this driver is stateless.
static NTSTATUS MarkRequestComplete(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
static NTSTATUS AkenCreate(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
{
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = 0;
@ -249,7 +238,17 @@ static NTSTATUS MarkRequestComplete(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
}
static NTSTATUS DeviceControl(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
static NTSTATUS AkenClose(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
{
// same as AkenCreate ATM
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
static NTSTATUS AkenDeviceControl(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
{
// get buffer from IRP. all our IOCTLs are METHOD_BUFFERED, so buf is
// allocated by the I/O manager and used for both input and output.
@ -269,9 +268,9 @@ static NTSTATUS DeviceControl(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
}
static VOID Unload(IN PDRIVER_OBJECT driverObject)
static VOID AkenUnload(IN PDRIVER_OBJECT driverObject)
{
KDPRINT(("Unload\n"));
KdPrint(("AkenUnload\n"));
UNICODE_STRING win32Name = RTL_CONSTANT_STRING(WIN32_NAME);
IoDeleteSymbolicLink(&win32Name);
@ -283,8 +282,6 @@ static VOID Unload(IN PDRIVER_OBJECT driverObject)
NTSTATUS DriverEntry(IN OUT PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath)
{
KDPRINT(("DriverEntry\n"));
UNICODE_STRING deviceName = RTL_CONSTANT_STRING(DEVICE_NAME);
// create device object
@ -296,16 +293,16 @@ NTSTATUS DriverEntry(IN OUT PDRIVER_OBJECT driverObject, IN PUNICODE_STRING regi
NTSTATUS ntStatus = IoCreateDevice(driverObject, deviceExtensionSize, &deviceName, FILE_DEVICE_AKEN, deviceCharacteristics, exlusive, &deviceObject);
if(!NT_SUCCESS(ntStatus))
{
KDPRINT(("IoCreateDevice failed\n"));
KdPrint(("DriverEntry: IoCreateDevice failed\n"));
return ntStatus;
}
}
// set entry points
driverObject->MajorFunction[IRP_MJ_CREATE] = MarkRequestComplete;
driverObject->MajorFunction[IRP_MJ_CLOSE] = MarkRequestComplete;
driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControl;
driverObject->DriverUnload = Unload;
driverObject->MajorFunction[IRP_MJ_CREATE] = AkenCreate;
driverObject->MajorFunction[IRP_MJ_CLOSE] = AkenClose;
driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AkenDeviceControl;
driverObject->DriverUnload = AkenUnload;
// symlink NT device name to Win32 namespace
{
@ -313,7 +310,7 @@ NTSTATUS DriverEntry(IN OUT PDRIVER_OBJECT driverObject, IN PUNICODE_STRING regi
NTSTATUS ntStatus = IoCreateSymbolicLink(&win32Name, &deviceName);
if(!NT_SUCCESS(ntStatus))
{
KDPRINT(("IoCreateSymbolicLink failed\n"));
KdPrint(("DriverEntry: IoCreateSymbolicLink failed\n"));
IoDeleteDevice(deviceObject);
return ntStatus;
}

View File

@ -14,7 +14,6 @@
#include <winioctl.h>
#include "aken/aken.h"
#include "wutil.h"
#include "lib/path_util.h"
#include "lib/module_init.h"
@ -76,8 +75,7 @@ static void WritePort(u16 port, u32 value, u8 numBytes)
DWORD bytesReturned; // unused but must be passed to DeviceIoControl
LPOVERLAPPED ovl = 0; // synchronous
BOOL ok = DeviceIoControl(hAken, (DWORD)IOCTL_AKEN_WRITE_PORT, &in, sizeof(in), 0, 0u, &bytesReturned, ovl);
if(!ok)
WARN_WIN32_ERR;
WARN_IF_FALSE(ok);
}
void mahaf_WritePort8(u16 port, u8 value)
@ -126,8 +124,7 @@ void mahaf_UnmapPhysicalMemory(void* virtualAddress)
DWORD bytesReturned; // unused but must be passed to DeviceIoControl
LPOVERLAPPED ovl = 0; // synchronous
BOOL ok = DeviceIoControl(hAken, (DWORD)IOCTL_AKEN_UNMAP, &in, sizeof(in), 0, 0u, &bytesReturned, ovl);
if(!ok)
WARN_WIN32_ERR;
WARN_IF_FALSE(ok);
}
@ -135,16 +132,6 @@ void mahaf_UnmapPhysicalMemory(void* virtualAddress)
// driver installation
//-----------------------------------------------------------------------------
static bool Is64BitOs()
{
#if OS_WIN64
return true;
#else
return wutil_IsWow64();
#endif
}
static SC_HANDLE OpenServiceControlManager()
{
LPCSTR machineName = 0; // local
@ -206,33 +193,26 @@ static void StartDriver(const char* driverPathname)
if(!hSCM)
return;
SC_HANDLE hService = OpenService(hSCM, AKEN_NAME, SERVICE_ALL_ACCESS);
#if 0
// during development, we want to unload and re-create the
// service every time to ensure the newest build is used.
BOOL ok = CloseServiceHandle(hService);
WARN_IF_FALSE(ok);
hService = 0;
UninstallDriver();
#endif
// create service (note: this just enters the service into SCM's DB;
// no error is raised if the driver binary doesn't exist etc.)
SC_HANDLE hService;
if(!hService)
{
create:
LPCSTR startName = 0; // LocalSystem
hService = CreateService(hSCM, AKEN_NAME, AKEN_NAME,
SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
driverPathname, 0, 0, 0, startName, 0);
if(!hService)
{
// was already created
if(GetLastError() == ERROR_SERVICE_EXISTS)
{
#if 1
// during development, we want to unload and re-create the
// service every time to ensure the newest build is used.
UninstallDriver();
goto create;
#else
// in final builds, just use the existing service.
hService = OpenService(hSCM, AKEN_NAME, SERVICE_ALL_ACCESS);
#endif
}
else
debug_assert(0); // creating actually failed
}
debug_assert(hService != 0);
}
// start service
@ -252,6 +232,27 @@ create:
}
static bool Is64BitOs()
{
#if OS_WIN64
return true;
#else
return wutil_IsWow64();
#endif
}
static void GetDriverPathname(char* driverPathname, size_t maxChars)
{
const char* const bits = Is64BitOs()? "64" : "";
#ifdef NDEBUG
const char* const debug = "";
#else
const char* const debug = "d";
#endif
sprintf_s(driverPathname, maxChars, "%s\\aken%s%s.sys", win_exe_dir, bits, debug);
}
//-----------------------------------------------------------------------------
static ModuleInitState initState;
@ -262,8 +263,7 @@ bool mahaf_Init()
return true;
char driverPathname[PATH_MAX];
const char* const driverName = Is64BitOs()? "aken64.sys" : "aken.sys";
(void)path_append(driverPathname, win_exe_dir, driverName);
GetDriverPathname(driverPathname, ARRAY_SIZE(driverPathname));
StartDriver(driverPathname);

View File

@ -75,7 +75,8 @@ LibError CounterHPET::Activate()
void CounterHPET::Shutdown()
{
mahaf_UnmapPhysicalMemory((void*)m_hpetRegisters);
if(m_hpetRegisters)
mahaf_UnmapPhysicalMemory((void*)m_hpetRegisters);
acpi_Shutdown();
mahaf_Shutdown();

View File

@ -17,6 +17,11 @@
class CounterHPET : public ICounter
{
public:
CounterHPET()
: m_hpetRegisters(0)
{
}
virtual const char* Name() const
{
return "HPET";

View File

@ -18,6 +18,11 @@ static const i64 PMT_FREQ = 3579545; // (= master oscillator frequency/4)
class CounterPMT : public ICounter
{
public:
CounterPMT()
: m_portAddress(0xFFFF)
{
}
virtual const char* Name() const
{
return "PMT";

View File

@ -16,6 +16,11 @@
class CounterQPC : public ICounter
{
public:
CounterQPC()
: m_frequency(-1)
{
}
virtual const char* Name() const
{
return "QPC";

View File

@ -39,8 +39,6 @@ public:
* (e.g. when using TSC: cpu_ClockFrequency isn't exact).
**/
virtual double NominalFrequency() const;
private:
};
#endif // #ifndef INCLUDED_TSC

View File

@ -64,6 +64,7 @@ static ICounter* ConstructCounterAt(uint id, void* address, size_t& size)
// counters are chosen according to the following order. rationale:
// - TSC must come before QPC and PMT to make sure a bug in the latter on
// Pentium systems doesn't come up.
// - PMT works, but is inexplicably slower than QPC on a PIII Mobile.
// - TGT really isn't as safe as the others, so it should be last.
// - low-overhead and high-resolution counters are preferred.
switch(id)
@ -73,9 +74,9 @@ static ICounter* ConstructCounterAt(uint id, void* address, size_t& size)
case 1:
CREATE(HPET)
case 2:
CREATE(PMT)
case 3:
CREATE(QPC)
case 3:
CREATE(PMT)
case 4:
CREATE(TGT)
default:

View File

@ -11,6 +11,8 @@
#include "precompiled.h"
#include "winit.h"
#include "win.h" // GetTickCount
typedef LibError (*PfnLibErrorVoid)(void);
@ -44,11 +46,16 @@ PfnLibErrorVoid shutdownEnd = 0;
**/
static void CallFunctionPointers(PfnLibErrorVoid* begin, PfnLibErrorVoid* end)
{
const DWORD t0 = GetTickCount();
for(PfnLibErrorVoid* ppfunc = begin; ppfunc < end; ppfunc++)
{
if(*ppfunc)
(*ppfunc)();
}
const DWORD t1 = GetTickCount();
debug_printf("WINIT/ total elapsed time in callbacks %d ms (+-10)\n", t1-t0);
}

View File

@ -161,8 +161,14 @@ static void GetDirectories()
{
GetSystemDirectory(win_sys_dir, sizeof(win_sys_dir));
if(GetModuleFileName(GetModuleHandle(0), win_exe_dir, MAX_PATH) != 0)
path_strip_fn(win_exe_dir);
const DWORD len = GetModuleFileName(GetModuleHandle(0), win_exe_dir, MAX_PATH);
debug_assert(len != 0);
// strip EXE filename and trailing slash
char* slash = strrchr(win_exe_dir, '\\');
if(slash)
*slash = '\0';
else
debug_assert(0); // directory name invalid?!
}

View File

@ -89,6 +89,7 @@ extern LibError LibError_from_win32(DWORD ret, bool warn_if_failed = true);
// directories
//
// neither of these end in a slash.
extern char win_sys_dir[MAX_PATH+1];
extern char win_exe_dir[MAX_PATH+1];