manual build.
aken: add provision for copying physical memory (safer than mapping) acpi uses that to avoid problems due to nonaligned ACPI tables (bonus: wastes less memory) wdbg: remove unnecessary headers wseh: add comments wstartup: fix return type (since we're now called by _initterm_e) This was SVN commit r5159.
This commit is contained in:
parent
a3c21bdfa4
commit
3e874c54cf
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -7,6 +7,7 @@
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// table utility functions
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -27,27 +28,32 @@ static u8 ComputeChecksum(const void* buf, size_t numBytes)
|
||||
// free() the returned pointer.
|
||||
static const AcpiTable* AllocateCopyOfTable(u64 physicalAddress)
|
||||
{
|
||||
// 4 KiB ought to be enough; if not, the table will be re-mapped.
|
||||
const size_t initialSize = 4*KiB;
|
||||
const AcpiTable* mappedTable = (const AcpiTable*)mahaf_MapPhysicalMemory(physicalAddress, initialSize);
|
||||
if(!mappedTable)
|
||||
// ACPI table sizes are not known until they've been mapped and copied.
|
||||
// since that is slow, we don't want to do it twice; solution is to copy
|
||||
// into a buffer big enough to hold a typical table. if it should be too
|
||||
// small, we map and copy again. using a temporary buffer, rather than
|
||||
// allocating that much up-front, avoids wasting memory for each table.
|
||||
static const size_t tempTableSize = 4*KiB;
|
||||
static u8 tempTableBuf[tempTableSize];
|
||||
const AcpiTable* tempTable = (const AcpiTable*)tempTableBuf;
|
||||
if(!mahaf_CopyPhysicalMemory(physicalAddress, tempTableSize, (void*)tempTable))
|
||||
return 0;
|
||||
const size_t size = mappedTable->size;
|
||||
|
||||
if(size > initialSize)
|
||||
// allocate the final table
|
||||
const size_t size = tempTable->size;
|
||||
const AcpiTable* table = (const AcpiTable*)malloc(size);
|
||||
if(!table)
|
||||
return 0;
|
||||
|
||||
// and fill it.
|
||||
if(size <= tempTableSize)
|
||||
cpu_memcpy((void*)table, tempTable, size);
|
||||
else
|
||||
{
|
||||
// re-map with correct size
|
||||
mahaf_UnmapPhysicalMemory((void*)mappedTable);
|
||||
mappedTable = (const AcpiTable*)mahaf_MapPhysicalMemory(physicalAddress, size);
|
||||
if(!mappedTable)
|
||||
if(!mahaf_CopyPhysicalMemory(physicalAddress, size, (void*)table))
|
||||
return 0;
|
||||
}
|
||||
|
||||
AcpiTable* table = (AcpiTable*)malloc(size);
|
||||
if(table)
|
||||
cpu_memcpy(table, mappedTable, size);
|
||||
|
||||
mahaf_UnmapPhysicalMemory((void*)mappedTable);
|
||||
return table;
|
||||
}
|
||||
|
||||
@ -175,7 +181,7 @@ struct RSDT
|
||||
u32 tables[1];
|
||||
};
|
||||
|
||||
// avoid std::map et al. because we are called before _cinit
|
||||
// avoid std::map et al. because we may be called before _cinit
|
||||
static const AcpiTable** tables;
|
||||
static size_t numTables;
|
||||
|
||||
|
@ -193,6 +193,29 @@ static NTSTATUS AkenIoctlUnmap(PVOID buf, const ULONG inSize, ULONG& outSize)
|
||||
return ntStatus;
|
||||
}
|
||||
|
||||
static NTSTATUS AkenIoctlCopyPhysical(PVOID buf, const ULONG inSize, ULONG& outSize)
|
||||
{
|
||||
if(inSize != sizeof(AkenCopyPhysicalIn) || outSize != 0)
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
const AkenCopyPhysicalIn* in = (const AkenCopyPhysicalIn*)buf;
|
||||
PHYSICAL_ADDRESS physicalAddress;
|
||||
physicalAddress.QuadPart = in->physicalAddress;
|
||||
const ULONG numBytes = (ULONG)in->numBytes;
|
||||
void* userBuffer = (void*)(UINT_PTR)in->userAddress;
|
||||
|
||||
PVOID kernelBuffer = MmMapIoSpace(physicalAddress, numBytes, MmNonCached);
|
||||
if(!kernelBuffer)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
// (this works because we're called in the user's context)
|
||||
RtlCopyMemory(userBuffer, kernelBuffer, numBytes);
|
||||
|
||||
MmUnmapIoSpace(kernelBuffer, numBytes);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS AkenIoctlUnknown(PVOID buf, const ULONG inSize, ULONG& outSize)
|
||||
{
|
||||
KdPrint(("AkenIoctlUnknown\n"));
|
||||
@ -219,6 +242,9 @@ static inline AkenIoctl AkenIoctlFromCode(ULONG ioctlCode)
|
||||
case IOCTL_AKEN_UNMAP:
|
||||
return AkenIoctlUnmap;
|
||||
|
||||
case IOCTL_AKEN_COPY_PHYSICAL:
|
||||
return AkenIoctlCopyPhysical;
|
||||
|
||||
default:
|
||||
return AkenIoctlUnknown;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#define IOCTL_AKEN_WRITE_PORT CTL_CODE(FILE_DEVICE_AKEN, AKEN_IOCTL+1, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_AKEN_MAP CTL_CODE(FILE_DEVICE_AKEN, AKEN_IOCTL+2, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_AKEN_UNMAP CTL_CODE(FILE_DEVICE_AKEN, AKEN_IOCTL+3, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_AKEN_COPY_PHYSICAL CTL_CODE(FILE_DEVICE_AKEN, AKEN_IOCTL+4, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
|
||||
// input and output data structures for the IOCTLs
|
||||
@ -67,6 +68,13 @@ struct AkenUnmapIn
|
||||
DWORD64 virtualAddress;
|
||||
};
|
||||
|
||||
struct AkenCopyPhysicalIn
|
||||
{
|
||||
DWORD64 physicalAddress;
|
||||
DWORD64 numBytes;
|
||||
DWORD64 userAddress;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif // #ifndef INCLUDED_AKEN
|
||||
|
@ -128,6 +128,26 @@ void mahaf_UnmapPhysicalMemory(void* virtualAddress)
|
||||
}
|
||||
|
||||
|
||||
bool mahaf_CopyPhysicalMemory(uintptr_t physicalAddress, size_t numBytes, void* buffer)
|
||||
{
|
||||
AkenCopyPhysicalIn in;
|
||||
in.physicalAddress = (DWORD64)physicalAddress;
|
||||
in.numBytes = (DWORD64)numBytes;
|
||||
in.userAddress = (DWORD64)buffer;
|
||||
|
||||
DWORD bytesReturned;
|
||||
LPOVERLAPPED ovl = 0; // synchronous
|
||||
BOOL ok = DeviceIoControl(hAken, (DWORD)IOCTL_AKEN_COPY_PHYSICAL, &in, sizeof(in), 0, 0, &bytesReturned, ovl);
|
||||
if(!ok)
|
||||
{
|
||||
WARN_WIN32_ERR;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// driver installation
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -195,13 +215,16 @@ static void StartDriver(const char* driverPathname)
|
||||
|
||||
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();
|
||||
#if 1
|
||||
// during development, we want to ensure the newest build is used, so
|
||||
// unload and re-create the service if it's running/installed.
|
||||
if(hService)
|
||||
{
|
||||
BOOL ok = CloseServiceHandle(hService);
|
||||
WARN_IF_FALSE(ok);
|
||||
hService = 0;
|
||||
UninstallDriver();
|
||||
}
|
||||
#endif
|
||||
|
||||
// create service (note: this just enters the service into SCM's DB;
|
||||
|
@ -27,4 +27,9 @@ extern void mahaf_WritePort32(u16 port, u32 value);
|
||||
extern void* mahaf_MapPhysicalMemory(uintptr_t physicalAddress, size_t numBytes);
|
||||
extern void mahaf_UnmapPhysicalMemory(void* virtualAddress);
|
||||
|
||||
/**
|
||||
* @return false on failure (insufficient paged pool?)
|
||||
**/
|
||||
extern bool mahaf_CopyPhysicalMemory(uintptr_t physicalAddress, size_t numBytes, void* buffer);
|
||||
|
||||
#endif // INCLUDED_MAHAF
|
||||
|
@ -11,16 +11,8 @@
|
||||
#include "precompiled.h"
|
||||
#include "wdbg.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <typeinfo>
|
||||
|
||||
#include "lib/bits.h"
|
||||
#include "lib/posix/posix_pthread.h"
|
||||
#include "lib/app_hooks.h"
|
||||
#include "lib/sysdep/cpu.h"
|
||||
#include "win.h"
|
||||
#include "wdbg_sym.h"
|
||||
#include "wutil.h"
|
||||
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
# define NEED_COOKIE_INIT
|
||||
#endif
|
||||
|
||||
// note: several excellent references are pointed to by comments below.
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// analyze an exception (determine description and locus)
|
||||
@ -292,6 +294,7 @@ unhandled SEH exceptions are caught:
|
||||
- with a vectored exception handler. this works across threads, but it's
|
||||
only available on WinXP (unacceptable). since it is called before __try
|
||||
blocks, we would receive expected/legitimate exceptions.
|
||||
(see http://msdn.microsoft.com/msdnmag/issues/01/09/hood/default.aspx)
|
||||
- by setting the per-process unhandled exception filter. as above, this works
|
||||
across threads and is at least portable across Win32. unfortunately, some
|
||||
Win32 DLLs appear to register their own handlers, so this isn't reliable.
|
||||
@ -306,7 +309,9 @@ dialog (it is able to jump directly to the offending code).
|
||||
wrapping all threads in a __try appears to be the best choice. unfortunately,
|
||||
we cannot retroactively install an SEH handler: the OS ensures SEH chain
|
||||
nodes are on the thread's stack (as defined by NT_TIB) in ascending order.
|
||||
(the handler would also have to be marked via .safeseh, but that is doable)
|
||||
(see http://www.microsoft.com/msj/0197/exception/exception.aspx)
|
||||
the handler would also have to be marked via .safeseh, but that is doable
|
||||
(see http://blogs.msdn.com/greggm/archive/2004/07/22/191544.aspx)
|
||||
consequently, we'll have to run within a __try; if the init code is to be
|
||||
covered, this must happen within the program entry point.
|
||||
|
||||
@ -321,6 +326,7 @@ C++ classes. this way is more reliable/documented, but has several drawbacks:
|
||||
- a new fat exception class would have to be created to hold the
|
||||
SEH exception information (e.g. CONTEXT for a stack trace), and
|
||||
- this information would not be available for C++ exceptions.
|
||||
(see http://blogs.msdn.com/cbrumme/archive/2003/10/01/51524.aspx)
|
||||
|
||||
*/
|
||||
|
||||
|
@ -87,13 +87,14 @@ application, not the CRT DLL.)
|
||||
|
||||
// reference: see http://www.codeguru.com/cpp/misc/misc/threadsprocesses/article.php/c6945__1
|
||||
|
||||
EXTERN_C void wstartup_InitAndRegisterShutdown()
|
||||
EXTERN_C int wstartup_InitAndRegisterShutdown()
|
||||
{
|
||||
winit_CallInitFunctions();
|
||||
atexit(winit_CallShutdownFunctions);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma data_seg(".CRT$XIV") // after C init, after XIU ("User") block
|
||||
EXTERN_C void(*wstartup_pInitAndRegisterShutdown)() = wstartup_InitAndRegisterShutdown;
|
||||
EXTERN_C int(*wstartup_pInitAndRegisterShutdown)() = wstartup_InitAndRegisterShutdown;
|
||||
#pragma data_seg()
|
||||
#pragma comment(linker, "/include:_wstartup_pInitAndRegisterShutdown")
|
||||
|
Loading…
Reference in New Issue
Block a user