[VIDEOPRT] [FORMATTING] No code change
[reactos.git] / win32ss / drivers / videoprt / int10.c
index 193607d..82f3774 100644 (file)
 
 #include "videoprt.h"
 
+#include <ndk/kefuncs.h>
+
+#define NDEBUG
+#include <debug.h>
+
 /* PRIVATE FUNCTIONS **********************************************************/
 
+#if defined(_M_IX86) || defined(_M_AMD64)
+NTSTATUS
+NTAPI
+IntInitializeVideoAddressSpace(VOID)
+{
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
+    NTSTATUS Status;
+    HANDLE PhysMemHandle;
+    PVOID BaseAddress;
+    LARGE_INTEGER Offset;
+    SIZE_T ViewSize;
+#ifdef _M_IX86
+    CHAR IVTAndBda[1024 + 256];
+#endif // _M_IX86
+
+    /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
+    BaseAddress = 0;
+    ViewSize = 1024 * 1024;
+    Status = ZwFreeVirtualMemory(NtCurrentProcess(),
+                                 &BaseAddress,
+                                 &ViewSize,
+                                 MEM_RELEASE);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Couldn't unmap reserved memory (%x)\n", Status);
+        return 0;
+    }
+
+    /* Open the physical memory section */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &PhysMemName,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               NULL,
+                               NULL);
+    Status = ZwOpenSection(&PhysMemHandle,
+                           SECTION_ALL_ACCESS,
+                           &ObjectAttributes);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
+        return Status;
+    }
+
+    /* Map the BIOS and device registers into the address space */
+    Offset.QuadPart = 0xa0000;
+    ViewSize = 0x100000 - 0xa0000;
+    BaseAddress = (PVOID)0xa0000;
+    Status = ZwMapViewOfSection(PhysMemHandle,
+                                NtCurrentProcess(),
+                                &BaseAddress,
+                                0,
+                                ViewSize,
+                                &Offset,
+                                &ViewSize,
+                                ViewUnmap,
+                                0,
+                                PAGE_EXECUTE_READWRITE);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Couldn't map physical memory (%x)\n", Status);
+        ZwClose(PhysMemHandle);
+        return Status;
+    }
+
+    /* Close physical memory section handle */
+    ZwClose(PhysMemHandle);
+
+    if (BaseAddress != (PVOID)0xa0000)
+    {
+        DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
+                BaseAddress);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Allocate some low memory to use for the non-BIOS
+     * parts of the v86 mode address space
+     */
+    BaseAddress = (PVOID)0x1;
+    ViewSize = 0xa0000 - 0x1000;
+    Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+                                     &BaseAddress,
+                                     0,
+                                     &ViewSize,
+                                     MEM_RESERVE | MEM_COMMIT,
+                                     PAGE_EXECUTE_READWRITE);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status);
+        return Status;
+    }
+    if (BaseAddress != (PVOID)0x0)
+    {
+        DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
+                BaseAddress);
+        return 0;
+    }
+
+#ifdef _M_IX86
+    /* Get the real mode IVT and BDA from the kernel */
+    Status = NtVdmControl(VdmInitialize, IVTAndBda);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("NtVdmControl failed (status %x)\n", Status);
+        return Status;
+    }
+#endif // _M_IX86
+
+    /* Return success */
+    return STATUS_SUCCESS;
+}
+#else
+NTSTATUS
+NTAPI
+IntInitializeVideoAddressSpace(VOID)
+{
+    UNIMPLEMENTED;
+    NT_ASSERT(FALSE);
+    return STATUS_NOT_IMPLEMENTED;
+}
+#endif
+
 #if defined(_M_IX86)
-VP_STATUS NTAPI
+VP_STATUS
+NTAPI
 IntInt10AllocateBuffer(
-   IN PVOID Context,
-   OUT PUSHORT Seg,
-   OUT PUSHORT Off,
-   IN OUT PULONG Length)
+    IN PVOID Context,
+    OUT PUSHORT Seg,
+    OUT PUSHORT Off,
+    IN OUT PULONG Length)
 {
-   PVOID MemoryAddress;
-   NTSTATUS Status;
-   PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
-   KAPC_STATE ApcState;
-
-   TRACE_(VIDEOPRT, "IntInt10AllocateBuffer\n");
+    PVOID MemoryAddress;
+    NTSTATUS Status;
+    PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
+    KAPC_STATE ApcState;
 
-   IntAttachToCSRSS(&CallingProcess, &ApcState);
+    TRACE_(VIDEOPRT, "IntInt10AllocateBuffer\n");
 
-   MemoryAddress = (PVOID)0x20000;
-   Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &MemoryAddress, 0,
-      Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+    IntAttachToCSRSS(&CallingProcess, &ApcState);
 
-   if (!NT_SUCCESS(Status))
-   {
-      WARN_(VIDEOPRT, "- ZwAllocateVirtualMemory failed\n");
-      IntDetachFromCSRSS(&CallingProcess, &ApcState);
-      return ERROR_NOT_ENOUGH_MEMORY;
-   }
+    MemoryAddress = (PVOID)0x20000;
+    Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+                                     &MemoryAddress,
+                                     0,
+                                     Length,
+                                     MEM_COMMIT,
+                                     PAGE_EXECUTE_READWRITE);
+    if (!NT_SUCCESS(Status))
+    {
+        WARN_(VIDEOPRT, "- ZwAllocateVirtualMemory failed\n");
+        IntDetachFromCSRSS(&CallingProcess, &ApcState);
+        return ERROR_NOT_ENOUGH_MEMORY;
+    }
 
-   if (MemoryAddress > (PVOID)(0x100000 - *Length))
-   {
-      ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress, Length,
-         MEM_RELEASE);
-      WARN_(VIDEOPRT, "- Unacceptable memory allocated\n");
-      IntDetachFromCSRSS(&CallingProcess, &ApcState);
-      return ERROR_NOT_ENOUGH_MEMORY;
-   }
+    if (MemoryAddress > (PVOID)(0x100000 - *Length))
+    {
+        ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress, Length,
+            MEM_RELEASE);
+        WARN_(VIDEOPRT, "- Unacceptable memory allocated\n");
+        IntDetachFromCSRSS(&CallingProcess, &ApcState);
+        return ERROR_NOT_ENOUGH_MEMORY;
+    }
 
-   *Seg = (USHORT)((ULONG)MemoryAddress >> 4);
-   *Off = (USHORT)((ULONG)MemoryAddress & 0xF);
+    *Seg = (USHORT)((ULONG)MemoryAddress >> 4);
+    *Off = (USHORT)((ULONG)MemoryAddress & 0xF);
 
-   INFO_(VIDEOPRT, "- Segment: %x\n", (ULONG)MemoryAddress >> 4);
-   INFO_(VIDEOPRT, "- Offset: %x\n", (ULONG)MemoryAddress & 0xF);
-   INFO_(VIDEOPRT, "- Length: %x\n", *Length);
+    INFO_(VIDEOPRT, "- Segment: %x\n", (ULONG)MemoryAddress >> 4);
+    INFO_(VIDEOPRT, "- Offset: %x\n", (ULONG)MemoryAddress & 0xF);
+    INFO_(VIDEOPRT, "- Length: %x\n", *Length);
 
-   IntDetachFromCSRSS(&CallingProcess, &ApcState);
+    IntDetachFromCSRSS(&CallingProcess, &ApcState);
 
-   return NO_ERROR;
+    return NO_ERROR;
 }
 
-VP_STATUS NTAPI
+VP_STATUS
+NTAPI
 IntInt10FreeBuffer(
-   IN PVOID Context,
-   IN USHORT Seg,
-   IN USHORT Off)
+    IN PVOID Context,
+    IN USHORT Seg,
+    IN USHORT Off)
 {
-   PVOID MemoryAddress = (PVOID)((Seg << 4) | Off);
-   NTSTATUS Status;
-   PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
-   KAPC_STATE ApcState;
-   SIZE_T Size = 0;
-
-   TRACE_(VIDEOPRT, "IntInt10FreeBuffer\n");
-   INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
-   INFO_(VIDEOPRT, "- Offset: %x\n", Off);
-
-   IntAttachToCSRSS(&CallingProcess, &ApcState);
-   Status = ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress, &Size,
-      MEM_RELEASE);
-   IntDetachFromCSRSS(&CallingProcess, &ApcState);
-
-   return Status;
+    PVOID MemoryAddress = (PVOID)((Seg << 4) | Off);
+    NTSTATUS Status;
+    PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
+    KAPC_STATE ApcState;
+    SIZE_T Size = 0;
+
+    TRACE_(VIDEOPRT, "IntInt10FreeBuffer\n");
+    INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
+    INFO_(VIDEOPRT, "- Offset: %x\n", Off);
+
+    IntAttachToCSRSS(&CallingProcess, &ApcState);
+    Status = ZwFreeVirtualMemory(NtCurrentProcess(),
+                                 &MemoryAddress,
+                                 &Size,
+                                 MEM_RELEASE);
+
+    IntDetachFromCSRSS(&CallingProcess, &ApcState);
+
+    return Status;
 }
 
-VP_STATUS NTAPI
+VP_STATUS
+NTAPI
 IntInt10ReadMemory(
-   IN PVOID Context,
-   IN USHORT Seg,
-   IN USHORT Off,
-   OUT PVOID Buffer,
-   IN ULONG Length)
+    IN PVOID Context,
+    IN USHORT Seg,
+    IN USHORT Off,
+    OUT PVOID Buffer,
+    IN ULONG Length)
 {
-   PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
-   KAPC_STATE ApcState;
+    PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
+    KAPC_STATE ApcState;
 
-   TRACE_(VIDEOPRT, "IntInt10ReadMemory\n");
-   INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
-   INFO_(VIDEOPRT, "- Offset: %x\n", Off);
-   INFO_(VIDEOPRT, "- Buffer: %x\n", Buffer);
-   INFO_(VIDEOPRT, "- Length: %x\n", Length);
+    TRACE_(VIDEOPRT, "IntInt10ReadMemory\n");
+    INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
+    INFO_(VIDEOPRT, "- Offset: %x\n", Off);
+    INFO_(VIDEOPRT, "- Buffer: %x\n", Buffer);
+    INFO_(VIDEOPRT, "- Length: %x\n", Length);
 
-   IntAttachToCSRSS(&CallingProcess, &ApcState);
-   RtlCopyMemory(Buffer, (PVOID)((Seg << 4) | Off), Length);
-   IntDetachFromCSRSS(&CallingProcess, &ApcState);
+    IntAttachToCSRSS(&CallingProcess, &ApcState);
+    RtlCopyMemory(Buffer, (PVOID)((Seg << 4) | Off), Length);
+    IntDetachFromCSRSS(&CallingProcess, &ApcState);
 
-   return NO_ERROR;
+    return NO_ERROR;
 }
 
-VP_STATUS NTAPI
+VP_STATUS
+NTAPI
 IntInt10WriteMemory(
-   IN PVOID Context,
-   IN USHORT Seg,
-   IN USHORT Off,
-   IN PVOID Buffer,
-   IN ULONG Length)
+    IN PVOID Context,
+    IN USHORT Seg,
+    IN USHORT Off,
+    IN PVOID Buffer,
+    IN ULONG Length)
 {
-   PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
-   KAPC_STATE ApcState;
+    PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
+    KAPC_STATE ApcState;
 
-   TRACE_(VIDEOPRT, "IntInt10WriteMemory\n");
-   INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
-   INFO_(VIDEOPRT, "- Offset: %x\n", Off);
-   INFO_(VIDEOPRT, "- Buffer: %x\n", Buffer);
-   INFO_(VIDEOPRT, "- Length: %x\n", Length);
+    TRACE_(VIDEOPRT, "IntInt10WriteMemory\n");
+    INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
+    INFO_(VIDEOPRT, "- Offset: %x\n", Off);
+    INFO_(VIDEOPRT, "- Buffer: %x\n", Buffer);
+    INFO_(VIDEOPRT, "- Length: %x\n", Length);
 
-   IntAttachToCSRSS(&CallingProcess, &ApcState);
-   RtlCopyMemory((PVOID)((Seg << 4) | Off), Buffer, Length);
-   IntDetachFromCSRSS(&CallingProcess, &ApcState);
+    IntAttachToCSRSS(&CallingProcess, &ApcState);
+    RtlCopyMemory((PVOID)((Seg << 4) | Off), Buffer, Length);
+    IntDetachFromCSRSS(&CallingProcess, &ApcState);
 
-   return NO_ERROR;
+    return NO_ERROR;
 }
 
 VP_STATUS
@@ -159,7 +296,7 @@ IntInt10CallBios(
     IntAttachToCSRSS(&CallingProcess, &ApcState);
 
     /* Clear the context */
-    RtlZeroMemory(&BiosContext, sizeof(CONTEXT));
+    RtlZeroMemory(&BiosContext, sizeof(BiosContext));
 
     /* Fill out the bios arguments */
     BiosContext.Eax = BiosArguments->Eax;
@@ -173,8 +310,16 @@ IntInt10CallBios(
     BiosContext.SegEs = BiosArguments->SegEs;
 
     /* Do the ROM BIOS call */
+    (void)KeWaitForMutexObject(&VideoPortInt10Mutex,
+                               Executive,
+                               KernelMode,
+                               FALSE,
+                               NULL);
+
     Status = Ke386CallBios(0x10, &BiosContext);
 
+    KeReleaseMutex(&VideoPortInt10Mutex, FALSE);
+
     /* Return the arguments */
     BiosArguments->Eax = BiosContext.Eax;
     BiosArguments->Ebx = BiosContext.Ebx;
@@ -188,7 +333,12 @@ IntInt10CallBios(
 
     /* Detach and return status */
     IntDetachFromCSRSS(&CallingProcess, &ApcState);
-    if (NT_SUCCESS(Status)) return NO_ERROR;
+
+    if (NT_SUCCESS(Status))
+    {
+        return NO_ERROR;
+    }
+
     return ERROR_INVALID_PARAMETER;
 }
 #endif
@@ -199,7 +349,8 @@ IntInt10CallBios(
  * @implemented
  */
 
-VP_STATUS NTAPI
+VP_STATUS
+NTAPI
 VideoPortInt10(
     IN PVOID HwDeviceExtension,
     IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments)
@@ -212,7 +363,7 @@ VideoPortInt10(
 
     if (!CsrssInitialized)
     {
-       return ERROR_INVALID_PARAMETER;
+        return ERROR_INVALID_PARAMETER;
     }
 
     /* Attach to CSRSS */
@@ -231,7 +382,13 @@ VideoPortInt10(
     BiosContext.Ebp = BiosArguments->Ebp;
 
     /* Do the ROM BIOS call */
+    (void)KeWaitForMutexObject(&VideoPortInt10Mutex,
+                               Executive,
+                               KernelMode,
+                               FALSE,
+                               NULL);
     Status = Ke386CallBios(0x10, &BiosContext);
+    KeReleaseMutex(&VideoPortInt10Mutex, FALSE);
 
     /* Return the arguments */
     BiosArguments->Eax = BiosContext.Eax;
@@ -244,7 +401,12 @@ VideoPortInt10(
 
     /* Detach from CSRSS */
     IntDetachFromCSRSS(&CallingProcess, &ApcState);
-    if (NT_SUCCESS(Status)) return NO_ERROR;
+
+    if (NT_SUCCESS(Status))
+    {
+        return NO_ERROR;
+    }
+
     return ERROR_INVALID_PARAMETER;
 #else
     /* Not implemented for anything else than X86*/